amplitude ^ | /-- | / \ D | / \ S | / -------------//---- | A / \ | / \ R | / \ | / \ +--------------------------//------------> timeThe above is a schematic representation of how the loudness of a sound can vary from the start to the end of the sound, using what is called a ADSR curve, which we will simulate in tcl.ADSR stands for Attack, Decay, Sustain, and release, corresponding with the phases of a sound coming up, decaying, being sustained (for instance like the key on an organ bein held down), and finally dies away.On traditional synthesizers, there are knobs for these 3 rates (ADR) and level (S), so that each phase of the sound can be made to take as long as seems fitting to the synthesizer programmer.The envelope is not the waveshape of the actual sound, it's only an approximation of the amplitude of the sound, because a sound is always made of vibrating waves, in the range of 20 Herz to 20kHz, so that the amplitude is always an approximate of some kind, for instance the average root mean square power of the sound signal (in electrical or sound wave form), or the height at the top of the bottom of the wave (at the zero crossing of the derivative).The amplitude gaph can be seen as multiplied with the waveform of the sound source at each point in time.
Am I the only one who finds pages like these pretty far off-topic for a Tcler's Wiki? -jcw(Well, I don't determine that eventually, but it doesn't feel nice to be cut short before I bring in both Snack (an important tcl/tk package), programs that are written in tcl and graphs and interesting interactors written in Tk, and even a relevant and interesting hardware link with direc tcl/tk interaction. Am I the only one to feel miserable about such comments?

The envelope of a sound is perceptually important, and often overlooked in a fourier analysis, see:Yet the envelope itself influences the perceived and mathematical harmonics of the signal possibly quite a bit. Another important factor when dealing with sounds (as with tcl/tk's snack below) is frequency variation, see:In fact both envelope adding to a signal or sound and frequency changes will easily generate a theoretically unbounded spectrum, which makes correct sampling of the result impossible without breaking the Shannon sampling frequency condition. Considering the interest amoung tcl users in various kinds of signals and their processing, an important consideration, using the frequency analysis of snack this soon becomes clear, too.Using snack (version 2.2), I recorded a piano sound , a single note, which you can listen to from here [1] , and of which the (meanwhile well known) waves in the snack main 'xs' window look like this:

proc attack {npoints} { set o {} for {set i 0} {$i < $npoints} {incr i} { lappend o [expr 1-pow($npoints-$i,2)/pow($npoints,2) ] } return $o }The quadric is simple, and mainly is constructed by thinking about it's top being at point ($npoints,1.0), and it having a reasonable weight factor for the quadric. Later on I'll go into more elaborate synthesis of such practically useful waveshapes in overseeable tcl code.I'm not sure it's a good idea to take pow(..,2) as pow(...,2.0), though at some point it might be good to make sure all math is done in floating point.As a quick test for our application let's run the loop from the tcl prompt, printing the values:
% set npoints 10 ; for {set i 0} {$i < $npoints} {incr i} { puts [expr 1-pow($npoints-$i,2)/pow($npoints,2) ] } 0.0 0.19 0.36 0.51 0.64 0.75 0.84 0.91 0.96 0.99The values go up and eventualy reach 1 (well, nearly).To see the result on a bwise canvas, or on any Tk canvas of which the path is in the variable 'mc', this long oneliner can help:
$mc del gr1; set a [attack 32]; set al [llength $a]; set ag {}; for {set i 0} {$i < $al} {incr i} {lappend ag [expr 3*$i] [expr 300-300*[lindex $a $i] ] } ; eval $mc create line $ag -tag gr1Which shows the intended curveas a line on the canvas.With the same thinking, a quadric ADSR procedure can look like:
proc adsr {{attack 16} {decay 32} {sustain 0.5} {release 8} } { set o {} for {set i 0} {$i < $attack} {incr i} { lappend o [expr 1-pow($attack-$i,2)/pow($attack,2) ] } for {set i 0} {$i < $decay} {incr i} { lappend o [expr $sustain+(1.0-$sustain)*pow($decay-$i,2)/pow($decay,2) ] } for {set i 0} {$i < $release} {incr i} { lappend o [expr $sustain*pow($release-$i,2)/pow($release,2) ] } return $o }using this adapted oneliner
$mc del gr1; set a [adsr 32 64 0.7 32] ; set al [llength $a]; set ag {}; for {set i 0} {$i < $al} {incr i} { lappend ag [expr 3*$i] [expr 300-300*[lindex $a $i] ] } ; eval $mc create line $ag -tag gr1the following envelope can be graphed

$mc del gr1; # delete previous graph from canvas set a [adsr 128 256 0.7 64] ; # make list of envelope values set al [llength $a]; # get number of envelope samples set ag {}; # empty result for {set i 0} {$i < $al} {incr i} { lappend ag [expr 1*$i] \ [expr 150 - sin($i/3.1415)*150*[lindex $a $i] ] } ; eval $mc create line $ag -tag gr1The result looks like this:

http://82.170.247.158/Soundtest
Related pages: http://members.tripod.com/%7Etheover/bwiseapp.html



Category Sound | Category Plotting | Category Signal Processing