[TV] One of the main things signal processing persons will want, regardless of wether they want to do that in tcl, basic, C, matlab, mathematica/[maxima], matcad, or some other (often interpreted) language + environment, is to be ablo to do a fourier analysis. I'm sure some pages on this wiki exist to do some of that, but this is supposed to be a fundamental and practical approach. Important companions of this page, to understand the subject, and the tcl code, too, or because in my vision the subjects are relevant to a wide area of tcl signal processing (they also state why, usually) are: * [Tcl based signal processing fundamentals: Additive Wave Synthesis] * [Tcl based signal processing fundamentals: Frequency Modulation] First, lets make a few one-liners to de signal frequency analysis, first a 256 (tcl-list) sample sinewave (three wavelengths are fitted in the list in this case, so a third harmonic): set twopi 2.0*3.1415926535 set r {}; for {set i 0} {$i < 256} {incr i} {lappend r [expr sin( (3.0/4.0)*$twopi + 3.0 * $twopi*$i/256)] } To find a certain harmonic in the signal, we can use the well known [fourier] analysis, in this case in discrete form (multiplying the signal sample for sample with a certain harmonic component): set t 0.0; for {set i 0} {$i < 256} {incr i} {set t [expr $t+ [lindex $r $i] * sin( 3.0 * $twopi*$i/256)] } ; puts [ expr $t/([llength $r] /2.0)] The third harmonic returns a 'strength' of 1 (full amplitude), then the 3.0 above is replaced by 1.0 for fundamantal (1st harmonic) or another harmonic (smaller than 128) some number very close to zero (background numerical noise) is returned. I'd rather make an application which does something like this [http://82.168.209.239/Menu/jsmenu3.html] (Click on the left on Waveform Lab, Theory, View Applet, Making Wavews, Sine f=2) in tcl/tk, but I want to do other things first, and I don't know if something like it already exists. Lets first make sure we can get some of the important spectral lines from a [tcl]-list of samples, first, a fourier transform [proc] based on the above oneliner tries, and a filter for all components higher then 1e-10: proc modfourier { {s} } { set r {} set twopi 2.0*3.1415926535 for {set j 0} {$j < [expr [llength $s]/2]} {incr j} { set im 0.0 set re 0.0 for {set i 0} {$i < 256} {incr i} {set im [expr $im+ [lindex $s $i] * sin( [expr $j * $twopi*$i/256] )] }; for {set i 0} {$i < 256} {incr i} {set re [expr $re+ [lindex $s $i] * cos( [expr $j * $twopi*$i/256] )] }; lappend r [ expr sqrt($re*$re + $im*$im) / ([llength $s] /2.0)] } return $r } Mod is added to the proc name because the modulo is returned in the list of frequency components, and the phase is ignored. [http://82.168.209.239/Wiki/sine4.jpg] Using the tcl/tk code from [Tcl based signal processing fundamentals: Additive Wave Synthesis] the above graph of the wave was made. So what's the big deal with this fourier analysis? That we can find frequency components in signals. In fact if we take all components from the above transform of a limited signal, we can find back the samples from that sampled signal by fourier synthesis (see page above), and it can be proven that the fourier basis (that is the sine and cosine components seperately) can uniquely represent any signal as long as it has no frequency components higher than half the sample rate (harmonic 127 in the example). Mathematically speaking, the transform is then perfectly invertable. Wrt interpretation: the sine waves are like principal components for instance in a sound. Our ears mainly hear frequency components like these, though of course they vary with time, rather than sound pressure waves amplitude. The above procedure isn't fast by algoritm or optimization. Probably the tcl code could be optimized by reusing variables and such, but mainly, most signal processing algorithms rely on what is called the Fast Fourier Transform, which does the same job as the above [proc] but reuses computed intermedeate results using a smart (well known) mathematical rearrangement of the computations. Now lets put the transform to work, we for instance use the above signal, stored as a tcl list of sampled values in variable r: set i 0; foreach j [modfourier $r ] {if {[expr abs($j)] > 1e-9} {puts "$i $j"} ; incr i} 3 0.999999999977 Listing only components larger than 1e-9 (1 in a billion, that's fairly accurate) we only get the expected frequency of 3 times the reciprocal sample length, which is fine.