%! % A modified efficient digital sinewave algorithm scanner % ===================================== % Don Lancaster and Synergetics www.tinaja.com % Some ultra compact low end digital sinewave generators % were described in Column 85 of https://www.tinaja.com/glib/hackar4.pdf % It appears that better performance and lower distortion can be % had by making the initial triangle approximation look more like % a true cosine wave. This can be done by adding adjustments to a % simple clipping. At a penalty of only a few bytes extra. % This code scans for candidate sinewaves having no dc offset and % a "unity" cosine match % This file is http://www.tinaja.com/psutils/sincat1.psl It is normally % run by sending the file to Distiller by way of command line //acrodist /F. % It should also be GhostScript or Google Drive compatible. % The companion demo is http://www.tinaja.com/psutils/sincat1.pdf % All distortions are BEFORE filtering! % Development services available via don@tinaja.com. % ///////// (A) WEB FRIENDLY COLOR UTILITIES ///////////// % tintmat is a self-generating list of 216 triple color values /webtintmat [ 0 1 5 { /a exch store 0 1 5 { /b exch store 0 1 5 { 5 div b 5 div a 5 div }for } for } for ] def % setwebtint accepts a color number 0 to 215 and then % sets the PostScript color generator for later use... /setwebtint { abs cvi 216 cvi mod % restrict range webtintmat exch 3 mul 3 getinterval % get values from table aload pop setrgbcolor} def % and set them % The blocks are arranged as red to the right, green % up in order of increasing blue. % Some "pure color" sequences are % red: 0 1 2 3 4 5 % orange: 0 7 8 15 16 23 (sort of) % yellow: 0 7 14 21 28 35 % green: 0 6 12 18 24 30 % aqua: 0 42 84 126 168 210 % blue: 0 36 72 108 144 180 % magenta: 0 37 74 111 148 185 % purple 0 73 73 110 147 183 (sort of) % gray 0 43 86 129 172 215 % ////////////// GONZO EXCERPTS ////////////////// /setgrid { /blocksize exch def translate % simplified blocksize dup scale} def % repeats [ proc distance trips] xrpt /xrpt{gsave aload pop /trips exch def /dist exch def /rproc exch def trips { gsave rproc grestore dist 0 translate } repeat grestore} def /yrpt{gsave aload pop /trips exch def /dist exch def /rproc exch def trips { gsave rproc grestore 0 dist translate } repeat grestore} def % mergestr merges the two top stack strings into one top stack string /mergestr {2 copy length exch length add string dup dup 4 3 roll 4 index length exch putinterval 3 1 roll exch 0 exch putinterval} def % convert an array of low integers into a string /makestring {dup length string dup /NullEncode filter 3 -1 roll {1 index exch write} forall pop} def /showgrid {gsave /vblocks exch def /hblocks exch def thingridlines setlinewidth [{0 0 moveto 0 vblocks rlineto stroke} 1 hblocks 1 add] xrpt [{0 0 moveto hblocks 0 rlineto stroke} 1 vblocks 1 add] yrpt fatterborder { gsave newpath 0 0.96 blocksize div dtransform round idtransform setlinewidth pop 2 setlinecap 0 0 moveto hblocks 0 rlineto 0 vblocks rlineto hblocks neg 0 rlineto closepath stroke grestore} if fat5 { gsave newpath 0 0.48 blocksize div dtransform round idtransform setlinewidth pop mark {5 0 moveto 0 vblocks rlineto stroke} 5 hblocks 5 div cvi] xrpt mark {0 5 moveto hblocks 0 rlineto stroke} 5 vblocks 5 div cvi] yrpt grestore} if fatter10 { gsave newpath 0 0.96 blocksize div dtransform round idtransform setlinewidth pop mark {10 0 moveto 0 vblocks rlineto stroke} 10 hblocks 10 div cvi] xrpt mark {0 10 moveto hblocks 0 rlineto stroke} 10 vblocks 10 div cvi] yrpt grestore} if grestore} def /fatterborder {true } store /fat5 {true} store /fatter10 {true} store /thingridlines {0} store /dot { currentpoint newpath 0.150 0 360 arc fill } def /mdot { moveto dot} def %%%%%%%%%%%%%%%%%%%%%%%% Fourier Service Module %%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%% fourier begins here %%%%%%%%%%%%%%%%% zzz /findfourier { % based on skilling 443 % (\nentering findfor with signal of ) print signal == signal length 1 sub /points exch store 360 points div /inc exch store 0 % fundamental cosine 1 1 points { /posn exch store posn inc mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang cos mul add } for /intf1 exch points div store 0 % third harmonic cosine 1 1 points { /posn exch store posn inc mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang 3 mul cos mul add} for /intf3 exch points dup 0 eq {pop 0.00001} if div intf1 dup 0 eq {pop 0.00001} if div store % relative to fundamental 0 1 1 points { /posn exch store posn inc % fifth harmonic cosine mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang 5 mul cos mul add } for /intf5 exch points dup 0 eq {pop 0.00001} if div intf1 dup 0 eq {pop 0.00001} if div store 0 1 1 points { /posn exch store posn inc % seventh harmonic cosine mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang 7 mul cos mul add } for /intf7 exch points dup 0 eq {pop 0.00001} if div intf1 dup 0 eq {pop 0.00001} if div store 0 1 1 points { /posn exch store posn inc % ninth harmonic cosine mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang 9 mul cos mul add } for /intf9 exch points dup 0 eq {pop 0.00001} if div intf1 dup 0 eq {pop 0.00001} if div store 0 1 1 points { /posn exch store posn inc % eleventh harmonic cosine mul inc 2 div sub /ang exch store signal posn get signal posn 1 sub get add 2 div ang 11 mul cos mul add } for /intf11 exch points dup 0 eq {pop 0.00001} if div intf1 dup 0 eq {pop 0.00001} if div store intf3 dup mul % totl distortion 3-9 percent intf5 dup mul add intf7 dup mul add intf9 dup mul add sqrt 100 mul /totaldist exch store } store /fourierdemo { % test module only /signal [ % triangle wave -1/9 1/25 -1/49 1/81 slight errors normal for this sample 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] store findfourier intf1 == intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print } store % fourierdemo % comment to stop fourier test /findharmonics { % make sure speed is exactly one cycle! /cosval size store /sinval 0 store mark % start signal array cosval 0 1 speed 2 sub {pop increment cosval } for ] /signal exch store signal == % comment to stop report signal length == findfourier intf3 == intf5 == intf7 == intf9 == totaldist == % reportharms } store %%%%%%%%%%%%%%%%%%%%%%%%%%% end Fourier service modules %%%%%%%%%%%%%%%%%%% /showpeaks { 0 setlinewidth 5 setwebtint 0 0 moveto 48 0 rlineto stroke % pos sinsize 0 sinsize 10 div moveto 48 0 rlineto stroke % pos sinzsize 0 sinsize 10 div neg moveto 48 0 rlineto stroke % neg sinzsize 0 size 10 div moveto 48 0 rlineto stroke % pos size 0 size 10 div neg moveto 48 0 rlineto stroke % neg size } store /formatpage { makegrid showpeaks showfakecos showfakesin showrealcos showrealsin findharmonics printdata showpage } store /makegrid { 50 50 10 setgrid 32 setwebtint 50 60 showgrid 1 15 translate} store % the digital transformation incrementer... /increment { /sinval sinval cosval 0 gt {-1}{+1} % start the algorithm ifelse add store /cosval cosval sinval adjustsin dup /newval exch store add store} store /adjustsin { } store % not used here % The fake cosine and intended output /showfakecos { /cosval size store /sinval 0 store newpath 1 setlinejoin 1 setlinecap 0 cosval 10 div moveto 0 1 speed cycles mul {/posn exch store increment 0.1 0 rlineto posn 10 div 0.1 add % adjust original cosval 10 div lineto } for 210 setwebtint 0.1 setlinewidth 1 setlinecap 1 setlinejoin stroke}store % The fake intermediate sine /showfakesin { /cosval size store /sinval 0 store newpath 1 setlinejoin 1 setlinecap 0 0 moveto 0 1 speed cycles mul {/posn exch store increment 0.1 0 rlineto posn 10 div 0.1 pop 0 add % adjust original? newval 10 div neg lineto } for 190 setwebtint 0.1 setlinewidth 1 setlinecap 1 setlinejoin stroke}store %% a real sinewave of amplitude sinsize %%%%%% /showrealsin {86 setwebtint 0 setlinewidth 0 0 moveto 0 1 speed cycles mul {/posn exch store posn 10 div 0.05 sub % adjust? posn 360 mul speed div sin sinsize mul 10 div lineto } for stroke} store %% a real cosine wave of amplitude size %%%%%% /showrealcos {86 setwebtint 0 setlinewidth 0 size 10 div moveto 0 1 speed cycles mul {/posn exch store posn 10 div posn 360 mul speed div dup 3 mul cos size mul 10 div /h3 exch store % huh? cos size mul 10 div % h3 .02 mul sub 1.02 mul % allows h3 addition, etc lineto } for stroke} store /printdata1x { 0 15 translate /StoneSans-Bold findfont 1 scalefont setfont 0 setwebtint 1 10 moveto (Cosine Amplitude "size" : ) size 20 string cvs mergestr show 1 8.5 moveto (Cosine Time Period "speed" : ) speed 20 string cvs mergestr show 1 7 moveto (Adjusted Sin Amplitude "sinsize" : ) sinsize 20 string cvs mergestr show 1 5.5 moveto (Cycles Displayed : ) cycles 1000 string cvs mergestr show % 1 4 moveto (Sin Modified: Yes) show gsave currentdict /title known { /StoneSans-Bold findfont 2 scalefont setfont 4 26 moveto ( ) show title show } if grestore gsave % show the signal /vpos1 29 store 1 vpos1 moveto (Approximate Cosine Wave Output:) show /vpos1 vpos1 1.5 sub store 3 vpos1 moveto ([ ) show /wide speed 4 div cvi store 0 1 signal length 1 sub {/posn1 exch store signal posn1 get 20 string cvs show ( ) show posn1 1 add wide eq posn1 1 add wide 2 mul eq or posn1 1 add wide 3 mul eq or {/vpos1 vpos1 1.5 sub store 4 vpos1 moveto} if } for ( ]) show grestore mark 0 1 signal length 2 sub {/posn2 exch store signal posn2 get signal posn2 1 add get sub } for ] /internal exch store gsave % show the internal /vpos1 18 store 1 vpos1 moveto (Approximate Sine Wave Internal:) show /vpos1 vpos1 1.5 sub store 3 vpos1 moveto ([ ) show /wide speed 4 div cvi store 0 1 internal length 1 sub {/posn1 exch store internal posn1 get 5 string cvs show ( ) show posn1 1 add wide eq posn1 1 add wide 2 mul eq or posn1 1 add wide 3 mul eq or {/vpos1 vpos1 1.5 sub store 4 vpos1 moveto} if } for ( ]) show grestore { gsave /vpos 10 store 0 1 adjustsintext length 1 sub {/curline exch store 23 vpos moveto adjustsintext curline get show /vpos vpos 1.5 sub store } for grestore } pop % signal findfourier 25 10 moveto (Third Harmonic: ) show intf3 100 mul 15 string cvs show ( percent.) show 25 8.5 moveto (Fifth Harmonic: ) show intf5 100 mul 15 string cvs show ( percent.) show 25 7 moveto (Seventh Harmonic: ) show intf7 100 mul 15 string cvs show ( percent.) show 25 5.5 moveto (Ninth Harmonic: ) show intf9 100 mul 15 string cvs show ( percent.) show 25 4 moveto ( THD 3 - 9 : ) show totaldist 1.0 mul 15 string cvs show ( percent.) show } store % hard 20 data for hardimage /signal [ 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] store findfourier /h20.3 intf3 store /h20.5 intf5 store /h20.7 intf7 store /h20.9 intf9 store /h20.t totaldist store % hard 19 /signal [ 19 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -19 -19 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 19 ] store findfourier /h19.3 intf3 store /h19.5 intf5 store /h19.7 intf7 store /h19.9 intf9 store /h19.t totaldist store % hard 18 /signal [ 18 18 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -18 -18 -18 -18 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 18 ] store findfourier /h18.3 intf3 store /h18.5 intf5 store /h18.7 intf7 store /h18.9 intf9 store /h18.t totaldist store % hard 17 /signal [ 17 17 17 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -17 -17 -17 -17 -17 -17 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 17 17 17 ] store findfourier /h17.3 intf3 store /h17.5 intf5 store /h17.7 intf7 store /h17.9 intf9 store /h17.t totaldist store % hard 16 /signal [ 16 16 16 16 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -16 -16 -16 -16 -16 -16 -16 -16 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 16 16 16 16] store findfourier /h16.3 intf3 store /h16.5 intf5 store /h16.7 intf7 store /h16.9 intf9 store /h16.t totaldist store % hard 15 /signal [ 15 15 15 15 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 15 15 15 15] store findfourier /h15.3 intf3 store /h15.5 intf5 store /h15.7 intf7 store /h15.9 intf9 store /h15.t totaldist store % hard 14 /signal [ 14 14 14 14 14 14 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -14 -14 -14 -14 -14 -14 -14 -14 -14 -14 -14 -14 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 14 14 14 14 14] store findfourier /h14.3 intf3 store /h14.5 intf5 store /h14.7 intf7 store /h14.9 intf9 store /h14.t totaldist store % hard 13 /signal [ 13 13 13 13 13 13 13 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 13 13 13 13 13] store findfourier /h13.3 intf3 store /h13.5 intf5 store /h13.7 intf7 store /h13.9 intf9 store /h13.t totaldist store % hard 12 /signal [ 12 12 12 12 12 12 12 12 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12 12 12 12 12] store findfourier /h12.3 intf3 store /h12.5 intf5 store /h12.7 intf7 store /h12.9 intf9 store /h12.11 intf11 store /h12.t totaldist store % hard 10 /signal [ 11 11 11 11 11 11 11 11 11 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 11 11 11 11 11] store findfourier /h11.3 intf3 store /h11.5 intf5 store /h11.7 intf7 store /h11.9 intf9 store /h11.11 intf11 store /h11.t totaldist store /hardimage { 100 160 18 setgrid 32 setwebtint 10 22 showgrid 0 10 translate 192 setwebtint 0.1 setlinewidth /mm { exch 10 sub exch 100 mul 2 copy (\n reporting ) print == (\n ) print == (\n\n) print mdot} store 20 h20.3 mm 19 h19.3 mm 18 h18.3 mm 17 h17.3 mm 16 h16.3 mm 15 h15.3 mm 14 h14.3 mm 13 h13.3 mm 12 h12.3 mm 11 h11.3 mm /pp { /rr exch 100 mul store /ll exch 100 mul store /xx exch 10 sub store xx ll moveto xx 1 add rr lineto stroke } store 19 h19.3 h20.3 pp % blue third harmonic 18 h18.3 h19.3 pp 17 h17.3 h18.3 pp 16 h16.3 h17.3 pp 15 h15.3 h16.3 pp 14 h14.3 h15.3 pp 13 h13.3 h14.3 pp 12 h12.3 h13.3 pp 11 h11.3 h12.3 pp 5 setwebtint % red fifth harmonic 20 h20.5 mm 19 h19.5 mm 18 h18.5 mm 17 h17.5 mm 16 h16.5 mm 15 h15.5 mm 14 h14.5 mm 13 h13.5 mm 12 h12.5 mm 11 h11.5 mm 19 h19.5 h20.5 pp 18 h18.5 h19.5 pp 17 h17.5 h18.5 pp 16 h16.5 h17.5 pp 15 h15.5 h16.5 pp 14 h14.5 h15.5 pp 13 h13.5 h14.5 pp 12 h12.5 h13.5 pp 11 h11.5 h12.5 pp /mmx { exch 10 sub exch mdot} store /ppx { /rr exch store /ll exch store /xx exch 10 sub store xx ll moveto xx 1 add rr lineto stroke } store 0 setwebtint % black total distortion 20 h20.t mmx 19 h19.t mmx 18 h18.t mmx 17 h17.t mmx 16 h16.t mmx 15 h15.t mmx 14 h14.t mmx 13 h13.t mmx 12 h12.t mmx 11 h11.t mmx 19 h19.t h20.t ppx 18 h18.t h19.t ppx 17 h17.t h18.t ppx % 16 h16.t h17.5 ppx % bug? 15 h15.t h16.t ppx 14 h14.t h15.t ppx 13 h13.t h14.t ppx 12 h12.t h13.t ppx % 11 h11.t h12.5 ppx % bug? 7 h17.t moveto 6 h16.t lineto stroke % gruesome patch unsolved 2 h12.t moveto 1 h11.t lineto stroke % gruesome patch unsolved 17 setwebtint % orange seventh harmonic 20 h20.7 mm 19 h19.7 mm 18 h18.7 mm 17 h17.7 mm 16 h16.7 mm 15 h15.7 mm 14 h14.7 mm 13 h13.7 mm 12 h12.7 mm 11 h11.7 mm 19 h19.7 h20.7 pp 18 h18.7 h19.7 pp 17 h17.7 h18.7 pp 16 h16.7 h17.7 pp 15 h15.7 h16.7 pp 14 h14.7 h15.7 pp 13 h13.7 h14.7 pp 12 h12.7 h13.7 pp 11 h11.7 h12.7 pp 184 setwebtint % burple ninth harmonic 20 h20.9 mm 19 h19.9 mm 18 h18.9 mm 17 h17.9 mm 16 h16.9 mm 15 h15.9 mm 14 h14.9 mm 13 h13.9 mm 12 h12.9 mm 11 h11.9 mm 19 h19.9 h20.9 pp 18 h18.9 h19.9 pp 17 h17.9 h18.9 pp 16 h16.9 h17.9 pp 15 h15.9 h16.9 pp 14 h14.9 h15.9 pp 13 h13.9 h14.9 pp 12 h12.9 h13.9 pp 11 h11.9 h12.9 pp 0 setwebtint 0 setlinewidth % zero reference baseline 0 0 moveto 10 0 rlineto stroke /StoneSans-Bold findfont 0.7 scalefont setfont 0 setwebtint 0 -10 translate gsave -.4 -1.0 translate 0 0 moveto (.5) show 2 0 moveto (.6) show 4 0 moveto (.7) show 6 0 moveto (.8) show 8 0 moveto (.9) show 9.8 0 moveto (1.0) show grestore gsave -3 5.4 translate 90 rotate 0 0 moveto (PERCENTAGE DISTORTION) show grestore gsave % y axis -2.3 -.2 translate 0 0 moveto (-10%) show 0 5 moveto (- 5%) show 0 10 moveto ( 0%) show 0 15 moveto (+5%) show 0 20 moveto (+10%) show 0 22 moveto (+12%) show grestore 3.1 -2.2 moveto (CLIP LEVEL) show /StoneSans-Bold findfont 0.55 scalefont setfont 1.6 1.9 moveto (3rd harm) show 1.55 19 moveto (THD 3-7) show 3.7 5.3 moveto (5th harm) show 0.2 11.8 moveto (9th harm) show 0.05 8.3 moveto (7th harm) show /StoneSans-Bold findfont 1.25 scalefont setfont 3 23.3 moveto (Hard) show 2 -4 moveto (Clipping Levels vs Distortion) show } store /softimage { 100 160 18 setgrid 32 setwebtint 10 22 showgrid 0 10 translate 192 setwebtint 0.1 setlinewidth /mm { exch 10 sub exch 100 mul mdot} store 20 h20.3 mm 19 h19.3 mm 18 h18.3 mm 17 h17.3 mm 16 h16.3 mm 15 h15.3 mm 14 h14.3 mm 13 h13.3 mm 12 h12.3 mm 11 h11.3 mm /pp { /rr exch 100 mul store /ll exch 100 mul store /xx exch 10 sub store xx ll moveto xx 1 add rr lineto stroke } store 19 h19.3 h20.3 pp % blue third harmonic 18 h18.3 h19.3 pp 17 h17.3 h18.3 pp 16 h16.3 h17.3 pp 15 h15.3 h16.3 pp 14 h14.3 h15.3 pp 13 h13.3 h14.3 pp 12 h12.3 h13.3 pp 11 h11.3 h12.3 pp 5 setwebtint % red fifth harmonic 20 h20.5 mm 19 h19.5 mm 18 h18.5 mm 17 h17.5 mm 16 h16.5 mm 15 h15.5 mm 14 h14.5 mm 13 h13.5 mm 12 h12.5 mm 11 h11.5 mm 19 h19.5 h20.5 pp 18 h18.5 h19.5 pp 17 h17.5 h18.5 pp 16 h16.5 h17.5 pp 15 h15.5 h16.5 pp 14 h14.5 h15.5 pp 13 h13.5 h14.5 pp 12 h12.5 h13.5 pp 11 h11.5 h12.5 pp /mmx { exch 10 sub exch mdot} store /ppx { /rr exch store /ll exch store /xx exch 10 sub store xx ll moveto xx 1 add rr lineto stroke } store 0 setwebtint % black total distortion 20 h20.t mmx 19 h19.t mmx 18 h18.t mmx 17 h17.t mmx 16 h16.t mmx 15 h15.t mmx 14 h14.t mmx 13 h13.t mmx 12 h12.t mmx 11 h11.t mmx 19 h19.t h20.t ppx 18 h18.t h19.t ppx 17 h17.t h18.t ppx % 16 h16.t h17.5 ppx % bug? 15 h15.t h16.t ppx 14 h14.t h15.t ppx 13 h13.t h14.t ppx 12 h12.t h13.t ppx % 11 h11.t h12.5 ppx % bug? 7 h17.t moveto 6 h16.t lineto stroke % gruesome patch unsolved 2 h12.t moveto 1 h11.t lineto stroke % gruesome patch unsolved 17 setwebtint % orange seventh harmonic 20 h20.7 mm 19 h19.7 mm 18 h18.7 mm 17 h17.7 mm 16 h16.7 mm 15 h15.7 mm 14 h14.7 mm 13 h13.7 mm 12 h12.7 mm 11 h11.7 mm 19 h19.7 h20.7 pp 18 h18.7 h19.7 pp 17 h17.7 h18.7 pp 16 h16.7 h17.7 pp 15 h15.7 h16.7 pp 14 h14.7 h15.7 pp 13 h13.7 h14.7 pp 12 h12.7 h13.7 pp 11 h11.7 h12.7 pp 184 setwebtint % burple ninth harmonic 20 h20.9 mm 19 h19.9 mm 18 h18.9 mm 17 h17.9 mm 16 h16.9 mm 15 h15.9 mm 14 h14.9 mm 13 h13.9 mm 12 h12.9 mm 11 h11.9 mm 19 h19.9 h20.9 pp 18 h18.9 h19.9 pp 17 h17.9 h18.9 pp 16 h16.9 h17.9 pp 15 h15.9 h16.9 pp 14 h14.9 h15.9 pp 13 h13.9 h14.9 pp 12 h12.9 h13.9 pp 11 h11.9 h12.9 pp 0 setwebtint 0 setlinewidth % zero reference baseline 0 0 moveto 10 0 rlineto stroke /StoneSans-Bold findfont 0.7 scalefont setfont 0 setwebtint 0 -10 translate gsave -.4 -1.0 translate 0 0 moveto (.5) show 2 0 moveto (.6) show 4 0 moveto (.7) show 6 0 moveto (.8) show 8 0 moveto (.9) show 9.8 0 moveto (1.0) show grestore gsave -3 5.4 translate 90 rotate 0 0 moveto (PERCENTAGE DISTORTION) show grestore gsave % y axis -2.3 -.2 translate 0 0 moveto (-10%) show 0 5 moveto (- 5%) show 0 10 moveto ( 0%) show 0 15 moveto (+5%) show 0 20 moveto (+10%) show 0 22 moveto (+12%) show grestore 3.1 -2.2 moveto (CLIP LEVEL) show /StoneSans-Bold findfont 0.55 scalefont setfont 3.3 11.8 moveto (3rd harm) show 0.3 14.3 moveto (THD 3-7) show 6.6 13.7 moveto (5th harm) show 7.3 9.2 moveto (9th harm) show 8 11.7 moveto (7th harm) show /StoneSans-Bold findfont 1.25 scalefont setfont 3 23.3 moveto (Soft) show % 2 -4 moveto (Clipping Levels vs Distortion) show % one title only } store %%%%%%%%%%%% recalculate soft %%%%%%%%%%%%%%%%% /newsoftcalc { /signal [ % twenty 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ] store findfourier /h20.3 intf3 store /h20.5 intf5 store /h20.7 intf7 store /h20.9 intf9 store /h20.t totaldist store /signal [ % nineteen 19 18 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -18 -19 -18 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 18 19 ] store findfourier /h19.3 intf3 store /h19.5 intf5 store /h19.7 intf7 store /h19.9 intf9 store /h19.t totaldist store /signal [ % eighteen 18 18 17 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -17 -18 -18 -17 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 17 18 18 ] store findfourier /h18.3 intf3 store /h18.5 intf5 store /h18.7 intf7 store /h18.9 intf9 store /h18.t totaldist store /signal [ % seventeen 17 17 17 16 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -16 -17 -17 -17 -16 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 16 17 17 17 ] store findfourier /h17.3 intf3 store /h17.5 intf5 store /h17.7 intf7 store /h17.9 intf9 store /h17.t totaldist store /signal [ % sixteen 16 16 16 16 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -15 -16 -16 -16 -16 -15 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 16 16 16 16] store findfourier /h16.3 intf3 store /h16.5 intf5 store /h16.7 intf7 store /h16.9 intf9 store /h16.t totaldist store /signal [ % fifteen 15 15 15 15 15 14 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -14 -15 -15 -15 -15 -15 -14 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 15 15 15 15 15] store findfourier /h15.3 intf3 store /h15.5 intf5 store /h15.7 intf7 store /h15.9 intf9 store /h15.t totaldist store /signal [ % fourteen 14 14 14 14 14 14 13 13 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -13 -14 -14 -14 -14 -14 -14 -13 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 13 14 14 14 14 14 14] store findfourier /h14.3 intf3 store /h14.5 intf5 store /h14.7 intf7 store /h14.9 intf9 store /h14.t totaldist store /signal [ % thirteen 13 13 13 13 13 13 13 12 12 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -12 -13 -13 -13 -13 -13 -13 -13 -12 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 12 13 13 13 13 13 13 13] store findfourier /h13.3 intf3 store /h13.5 intf5 store /h13.7 intf7 store /h13.9 intf9 store /h13.t totaldist store /signal [ % twelve 12 12 12 12 12 12 12 12 11 11 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -11 -12 -12 -12 -12 -12 -12 -12 -12 -11 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 11 12 12 12 12 12 12 12 12] store findfourier intf3 /h12.3 intf3 store /h12.5 intf5 store /h12.7 intf7 store /h12.9 intf9 store /h12.t totaldist store /signal [ % eleven 11 11 11 11 11 11 11 11 11 10 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -10 -11 -11 -11 -11 -11 -11 -11 -11 -11 -10 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 10 11 11 11 11 11 11 11 11 11] store findfourier /h11.3 intf3 store /h11.5 intf5 store /h11.7 intf7 store /h11.9 intf9 store /h11.11 intf11 store /h11.t totaldist store } store %%%%%%% display hard and soft on same page %%%%% uuu % Note that these distortion figures are for the "hidden" sine page. % As noted, they get significantly reduced by the integration to the % "output" cosine page. Because most integrations are also lowpass % filters. The present limit appears to be 0.24% before filtering. % Zero third appears possible in at least four cases, albeit with % with higher H5 and H7. save /hardsnap exch store hardimage hardsnap restore save /softsnap exch store 300 0 translate newsoftcalc softimage softsnap restore showpage { % bypassing intermediate code (\n\n\nstarting 10c3/16 demo\n\n) print /signal [ % 10C3/16 is third 10 10 10 10 10 9 9 8 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -8 -9 -9 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -9 -9 -8 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 8 9 9 10 10 10 10 10 ] store (\n\nclip 10c3 of 16 for sin dist\n\n) print % sin distortion findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print save /xsnap exch store (\n\n\nstarting fourier demo\n\n) print fourierdemo xsnap restore (\n\n\nstarting 10c3 again demo\n\n) print save /x1snap exch store /signal [ % 10C3/16 is third 10 10 10 10 10 9 9 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -9 -9 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -9 -9 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 9 9 10 10 10 10 10 ] store (\n\nclip 10c3 of 16 for sin dist\n\n) print % sin distortion findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print x1snap restore /zz [10 10 10 10 10 9 9 9 8 7 6 5 4 3 2 1 0 ] store /zz [10 10 10 9 9 8 8 8 7 6 6 5 4 3 2 1 0 ] store % 0 1 16 {16 div 90 mul cos ==} for 0 1 zz length 1 sub { /posn exch store posn 16 div 90 mul cos /cosval exch store zz posn get cosval 10 mul sub == } for % 5 2 2 gives -.025 3rd on sine best really soft 16 % 4 3 2 gives -.029 3rd on sine % 5 3 1 gives -.030 3rd on sine %%%%%%%%%%%%%%%%%% try new method %%%%%%%%%%%%%%% /target [ 1 2 3 4 5 6 7 8 8 9 9 10 10 10 10 10 ] store /expand { 0 target {add} forall /size exch store size == target length 4 mul /speed exch store speed == target dup length 1 sub get /sinsize exch store sinsize == mark % sin as cosine target length 1 sub -1 0 { /posn exch store target posn get} for 0 0 1 target length 1 sub {/posn exch store target posn get neg} for target length 1 sub -1 0 {/posn exch store target posn get neg } for 0 0 1 target length 1 sub {/posn exch store target posn get } for] /sinascosine exch store mark % sin as sin 0 1 target length 1 sub {target exch get} for target length 1 sub -1 0{target exch get } for 0 0 1 target length 1 sub {target exch get neg } for target length 1 sub -1 0 {target exch get neg} for ] /sinassine exch store mark % main output cosine size sinassine {exch dup 3 -1 roll sub } forall ] /newsignal exch store } store { expand sinascosine == (\n\n ) print sinassine == (\n\nnewsignal \n\n) print newsignal == (\n\n\n) print /signal {newsignal} store expand % sinassin == findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print (\n\n\n\n\n\n\n\n\n) print /target [ 1 2 3 4 5 6 7 8 8 9 9 9 10 10 10 10 ] store expand /signal {newsignal} store findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /target [ 1 2 3 4 5 6 7 8 9 9 9 10 10 10 10 10 ] store expand /signal {newsignal} store findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print /target [ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 ] store expand /signal {newsignal} store findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print } pop (\n\n\n\n\n\n\n) print % clip only 16 [ [ 1 2 3 4 5 6 7 8 9 9 9 9 9 9 9 9 ] [ 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10 ] [ 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 11 ] [ 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12 ] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 13 ] [ 1 2 3 4 5 6 7 8 9 9 10 10 10 10 10 10 ] [ 1 2 3 4 5 6 7 8 9 9 9 10 10 10 10 10 ] [ 1 2 3 4 5 6 7 8 8 9 9 9 10 10 10 10 ] [ 1 2 3 4 5 6 7 8] [ 1 2 3 4 5 6 7 7] [ 1 2 3 4 5 6 6 6] % hot no third 32 [ 1 2 3 4 5 5 5 5] [ 1 2 3 4 5 6 7 8 9] [ 1 2 3 4 5 6 7 8 8] [ 1 2 3 4 5 6 7 7 7] [ 1 2 3 4 5 6 6 6 6] [ 1 2 3 4 5 6 7 8 9 10 ] [ 1 2 3 4 5 6 7 8 9 9 ] [ 1 2 3 4 5 6 7 8 8 8 ] [ 1 2 3 4 5 6 7 7 7 7 ] [ 1 2 3 4 5 6 7 7 8 8 8 ] [ 1 2 3 4 5 6 7 8 8 8 8 ] % hot- no third! 60 44 8 SIMPLE CLIP IF VALID [ 1 2 3 4 5 6 7 8 9 ] [ 1 2 3 4 5 6 7 8 8 ] [ 1 2 3 4 5 6 6 7 7 ] % no cancel at 36 [ 1 2 3 4 5 6 7 7 7 ] [ 1 2 3 4 5 6 6 6 6 ] [1 2 3] [1 2 2] [1 2.415 3] [1 2.415 2.415] [ 1 2 3 4 5 6 7 8 9 10 ] [ 1 2 3 4 5 6 7 8 9 9 ] [ 1 2 3 4 5 6 7 8 8 8 ] [ 1 2 3 4 5 6 7 7 7 7 ] [ 1 2 3 4 5 6 6 7 7 7 ] % ok at 0.64 [ 1 2 3 4 5 6 7 8 9 10 11] [ 1 2 3 4 5 6 7 8 9 10 10] [ 1 2 3 4 5 6 7 8 9 9 9] [ 1 2 3 4 5 6 7 8 8 8 8] % NO THIRD .628 thd [ 1 2 3 4 5 6 7 7 8 8 8] % WINNER SO FAR .07 third .25 THD! [ 1 2 3 4 5 6 7 8 9 10 11 12] [ 1 2 3 4 5 6 7 8 9 10 11 11] [ 1 2 3 4 5 6 7 8 9 10 10 10] [ 1 2 3 4 5 6 7 8 9 9 9 9] % .50 .73 just ok [ 1 2 3 4 5 6 7 8 8 8 8 8] [ 1 2 3 4 5 6 7 7 8 8 8 8] [ 1 2 3 4 5 6 7 8 9 10 11 12 13] [ 1 2 3 4 5 6 7 8 9 10 11 12 12] [ 1 2 3 4 5 6 7 8 9 10 11 11 11] [ 1 2 3 4 5 6 7 8 9 10 10 10 10] [ 1 2 3 4 5 6 7 8 9 9 9 9 9] [ 1 2 3 4 5 6 7 8 8 9 9 9 9] % .48 .64 marginal size 80 [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 13] [ 1 2 3 4 5 6 7 8 9 10 11 12 12 12] [ 1 2 3 4 5 6 7 8 9 10 11 11 11 11] [ 1 2 3 4 5 6 7 8 9 10 10 10 10 10] % NO THIRD 0.67 size 95 [ 1 2 3 4 5 6 7 8 9 9 10 10 10 10] %.03 third .41 thd GOOD [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13] % .40 .72 size 110 [ 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12] [ 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11] [ 1 2 3 4 5 6 7 8 9 10 10 11 11 11 11] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 14] [ 1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 13] [ 1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12] [ 1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 11] [ 1 2 3 4 5 6 7 8 9 10 10 11 11 11 11 11] % .39 .67 120 [ 1 2 3 4 5 6 7 8 9 10 10 10 11 11 11 11] % .49 .64 119 ] /glotz { {/target exch store expand newsignal == sinassine == findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print /signal {newsignal} store (\n) print } forall } store glotz (\n\nwoof\n\n) print %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% single peak originals do not produce much in the way of clipped results %%%%%%%%%%%%%%%% single peak series %%%%%%%%%%%%% (\n\n\n\n\n\n single peak series \n\n) print %%% warning: sin as cosine still wrong /expand1 { 0 target {add} forall target dup length 1 sub get 2 div sub cvi /size exch store size == target length 4 mul /speed exch store speed == target dup length 1 sub get /sinsize exch store sinsize == mark % sin as cosine target length 2 sub -1 0 { /posn exch store target posn get} for 0 0 1 target length 1 sub {/posn exch store target posn get neg} for target length 1 sub -1 0 {/posn exch store target posn get neg } for 0 0 1 target length 1 sub {/posn exch store target posn get } for] /sinascosine exch store mark % sin as sin 0 1 target length 1 sub {target exch get} for target length 2 sub -1 0{target exch get } for 0 0 1 target length 1 sub {target exch get neg } for target length 2 sub -1 0 {target exch get neg} for ] /sinassine exch store mark % main output cosine size sinassine {exch dup 3 -1 roll sub } forall ] /newsignal exch store } store /glotz1 { {/target exch store expand1 newsignal == sinassine == findfourier intf3 == intf5 == intf7 == intf9 == totaldist == (\n) print /signal {newsignal} store (\n) print } forall } store (\n\neight unit original\n\n) print % marginal [ [1 2 3 4 5 6 7 8 ] % default 8 matches original at 3.10% size 32 [1 2 3 4 5 6 6 6 ] % .74/.83 [1 2 3 4 4 4 4 4 ] % too high [1 2 3 3 4 4 4 4 ] % too high ] glotz1 (\n\nten unit original\n\n) print % none useful [ [1 2 3 4 5 6 7 8 9 10] % default 3.24 thd third size 50 % [1 2 3 4 5 6 7 8 9 9] not valid [1 2 3 4 5 6 7 8 8 8] % 1.66/1.69 % [1 2 3 4 5 6 7 7 7 7] % NO THIRD 0.59 can't be odd % [1 2 3 4 5 6 6 7 7 7] % .11 Third 0.16 THD size 48 [1 2 3 4 5 6 6 6 6 6] % 2.08/2.22 [1 2 3 4 5 5 6 6 6 6] % 1.76 1.78 ] glotz1 (\n\ntwelve unit original\n\n) print % none useful [ [1 2 3 4 5 6 7 8 9 10 11 12] % default 3.342 size 72 [1 2 3 4 5 6 7 8 9 10 10 10] % toohigh [1 2 3 4 5 6 7 8 8 8 8 8] % .55/.91 [1 2 3 4 5 6 7 7 8 8 8 8] % .53/.63 OK ] glotz1 (\n\nfourteen unit original\n\n) print % none useful [ [1 2 3 4 5 6 7 8 9 10 11 12 13 14] % default 3.41 size 98 [1 2 3 4 5 6 7 8 9 10 11 12 12 12] % 2.53/2.57 too high [1 2 3 4 5 6 7 8 9 10 10 10 10 10] % .45/.73 ok [1 2 3 4 5 6 7 8 9 9 10 10 10 10] % .36/.48 USEFUL but soft size 89 [1 2 3 4 5 6 7 7 7 8 8 8 8 8] % 2.2/2.28 too high ] glotz1 (\n\nsixteen unit original\n\n) print [ [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] % default 3.45 size 128 OUT OF RANGE [1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 14] % 2.7/2.81 high 126 [1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12] % 1.1/1.2 high 120 [1 2 3 4 5 6 7 8 9 10 11 11 12 12 12 12] % 1.0/1.05 high 119 [1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 10] % .8/1.54 too high but largest size [1 2 3 4 5 6 7 8 9 9 9 10 10 10 10 10] % 1.2/1.3 too high ] glotz1 %%%%%%%%%%%%%%%% double peak series %%%%%%%%%%%%% % offers more useful results and potential third cancellations (\n\nseven unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 ] [1 2 3 4 5 6 6 ] [1 2 3 4 5 5 5 ] [1 2 3 4 4 4 4 ] ] glotz (\n\neight unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 ] % 2.87/2.99 size 36 [1 2 3 4 5 6 7 7 ] % 1.8/1.9 too high size 35 [1 2 3 4 5 6 6 6 ] % ZERO THIRD!!! 0.55 thd size 33 [1 2 3 4 5 5 6 6 ] % .18/.25 BEST OVERALL size 32 ] glotz (\n\nnine unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9] % 2.9 3.0 size 45 [1 2 3 4 5 6 7 8 8] % .63/.78 size 42 [1 2 3 4 5 6 7 7 7] % 1.4/1.6 too high 39 [1 2 3 4 5 6 6 6 6] ] glotz (\n\nten unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10] % [1 2 3 4 5 6 7 8 9 9] % [1 2 3 4 5 6 7 8 8 8] % [1 2 3 4 5 6 7 7 7 7] % .49/.88 81 [1 2 3 4 5 6 6 7 7 7 ] % .48/.64 80 soft clip [1 2 3 4 5 6 6 6 6 6] % too high [1 2 3 4 5 5 6 6 6 6] % too high [1 2 3 4 5 5 5 6 6 6] % too high ] glotz (\n\neleven unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11] % too high [1 2 3 4 5 6 7 8 9 10 10] % too high [1 2 3 4 5 6 7 8 9 9 9] % too high [1 2 3 4 5 6 7 8 8 8 8] % ZERO/.62 size 60 [1 2 3 4 5 6 7 7 7 7 7 ] % too high [1 2 3 4 5 6 6 7 7 7 7] % too high ] glotz (\n\ntwelve unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11 12] % [1 2 3 4 5 6 7 8 9 10 11 11] % [1 2 3 4 5 6 7 8 9 10 10 10] % [1 2 3 4 5 6 7 8 9 9 9 9] % .50/.73 72 [1 2 3 4 5 6 7 8 8 8 8 8 ] % [1 2 3 4 5 6 7 7 8 8 8 8 ] % ] glotz (\n\nthirteen unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11 12 13] % [1 2 3 4 5 6 7 8 9 10 11 12 12] % [1 2 3 4 5 6 7 8 9 10 10 10 10] % [1 2 3 4 5 6 7 8 9 9 9 9 9] % .49/88 81 [1 2 3 4 5 6 7 8 8 9 9 9 9] % .48/64 80 soft [1 2 3 4 5 6 7 8 8 8 9 9 9] % [1 2 3 4 5 6 7 8 8 8 8 8 8] % [1 2 3 4 5 6 7 7 7 8 8 8 8] % ] glotz (\n\nfourteen unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11 12 13 14] % [1 2 3 4 5 6 7 8 9 10 11 12 13 13] % [1 2 3 4 5 6 7 8 9 10 11 11 11 11] % [1 2 3 4 5 6 7 8 9 10 10 10 10 10] % ZERO/.67 95 [1 2 3 4 5 6 7 8 9 9 10 10 10 10] % too big ] glotz (\n\nfifteen unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15] % [1 2 3 4 5 6 7 8 9 10 11 12 13 14 14] % [1 2 3 4 5 6 7 8 9 10 11 12 12 12 12] % [1 2 3 4 5 6 7 8 9 10 11 11 11 11 11] % .409/.727 110 [1 2 3 4 5 6 7 8 9 10 10 11 11 10 11] % ZERO/.57 108 soft ] glotz (\n\nsixteen unit double peaked\n\n) print % [ [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] % [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15] % [1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 14] % [1 2 3 4 5 6 7 8 9 10 11 12 13 13 13 13] % [1 2 3 4 5 6 7 8 9 10 11 11 11 11 11 11] % .40/.86 121 [1 2 3 4 5 6 7 8 9 10 10 10 11 11 11 11] % .49/.64 soft 119 ] glotz % missing: 8 hard clipped 40 ignore at 2.6637% these are all single peaked % 8 hard cliped 56 good .56/.75 single peaked 11 unit needs checked % 8 hard clipped 72 1.59/1.57 ignore % 8 hard clipped 80 2.5/2.67 ignore % 8 hard clipped 88 3.38/3.46 ignore % 8 hard clipped 96 4.12/4.17 ignore % 8 hard clipped 104 4.78/4.811ignore % 8 hard clipped 112 5.35/5.37 ignore % 8 hard clipped 120 5.86/5.87 ignore % 8 soft clipped 39 1.77/1.80 ignore % 8 soft clipped 47 1.21/1.22 ignore? % 8 soft cliped 55 .38/.41 BEST WE GOTTA PROBLEM FRIX % 8 soft clipped 63 .53/.63 THIS NEEDS FIXED TOO % 8 soft clipped 71 1.45/1.52 % 8 soft clipped 79 2.31/2.37 ignore % 8 soft clipped 87 3.11/3.15 ignore % 8 soft clipped 95 3.83/3.85 ignore % 8 soft clipped 103 4.47/4.48 ignore % 8 soft clipped 111 5.04/5.05 ignore % 8 soft clipped 119 5.55/5.56 ignore % 10 soft clipped 59 2.29/2.33 ignore % 10 soft clipped 69 1.82/1.84 ignore % 10 soft clipped 79 1.13/1.14 ignore? % 10 soft clipped 89 .36/.48 OLD BEST NEEDS FIXED ! % 10 soft clipped 99 .43/.66 NEEDS FIXED % 10 soft clipped 109 1.21/1.36 ignore % 10 soft clipped 119 2.11/2.66 ignore % 12 soft clipped 83 2.61/2.66 ignore % 12 soft clipped 95 2.23/2.25 ignore % 12 soft clipped 107 1.67/1.69 ignore % 12 soft clipped 119 1.01/1.05 ignore? % 14 soft clipped 111 /2.82/2.89 ignore % 14 soft clipped 125 /2.51/2.55 ignore % 10 hard 40 3.04/3.18 TITLE ERROR % 10 hard 50 3.11/3.24 TITLE ERROR % 10 hard 60 2.85/2.04 TITLE ERROR % 10 hard 70 2.19/2.22 TITLE ERROR % 10 hard 80 1.35/1.39 % 10 hard 90 .45/.73 IMPORTANT! % 10 hard 100 .44/.87 IMPORTANT! % 10 hard 110 1.29/1.54 ignore % 10 hard 120 2.07/2.25 ignore % 12 hard 84 3.02/3.12 ignroe % 12 hard 96 2.53/2.57 ignore % 12 hard 108 1.87/1.89 ignore % 12 hard 120 1.13/1.21 ignore % 12 hard 132 .37/72 ADD BUT OUT OF RANGE % 16 soft 79 1.13/1.14 ignore % 16 soft 89 .36/.48 IMPORTANT! % 16 soft 99 .43/.66 IMPORTANT! % 16 soft 109 1.21/1.36 ignore % 16 soft 119 1.95 2.06 ignore % eof } pop %%%%%%%%%%%%%%%% plot clipping waveforms %%%%%%%%%%%%%%%%%%%%% % These predict what can be accomplished with hard and soft clips. % Zero third harmonics appear possible by using a double clip. % The THD limit apparently is around 0.24 percent total. %%%%%%%%%%%%%%%%%% single peak front end %%%%%%%%%%%%%%% /report true store % debugger % /findsinglepeaks generates the plots for initial triangles and % companion hard or soft clips having a single waveform peak. These % will always have a non-zero third harmonic, bot otherwise may be % quite useful. /findsinglepeaks { % single peaks include triangles /curdat exch store curdat { % start forall loop dup 0 get /target exch store 1 get /title exch store report { target ==} if report {title == } if /intsin mark 0 1 target length 1 sub {target exch get} for target length 2 sub -1 0 {target exch get} for 0 0 1 target length 1 sub {target exch get neg} for target length 2 sub -1 0 {target exch get neg} for ] store report { target ==} if report{intsin == } if /sinsize target dup length 1 sub get store report {sinsize == } if /size 0 target{add} forall sinsize 2 div cvi sub store % sinsize must be even! /speed target length 4 mul store report { size == } if /cyclewidth 480 store % 10x display width /cycles cyclewidth speed div floor cvi store report { cycles == } if report { speed == } if /output mark size intsin{exch dup 3 -1 roll sub } forall ] store report {output ==} if (\n\n\n) print /signal output store findfourier (\n\n\n thd is now ) print totaldist == formatpage } forall } store /finddoublepeaks { % single peaks include triangles /curdat exch store curdat { % start forall loop dup 0 get /target exch store 1 get /title exch store report { target ==} if report {title == } if /intsin mark 0 1 target length 1 sub {target exch get} for target length 1 sub -1 0 {target exch get} for 0 0 1 target length 1 sub {target exch get neg} for target length 1 sub -1 0 {target exch get neg} for ] store report { target ==} if report{intsin == } if /sinsize target dup length 1 sub get store report {sinsize == } if /size 0 target{add} forall % sinsize 2 div cvi sub store % sinsize must be even! /speed target length 4 mul store report { size == } if /cyclewidth 480 store % 10x display width /cycles cyclewidth speed div floor cvi store report { cycles == } if report { speed == } if /output mark size intsin{exch dup 3 -1 roll sub } forall ] store report {output ==} if (\n\n\n) print /signal output store findfourier (\n\n\n thd is now ) print totaldist == formatpage } forall } store /showfakecos { % revised from original /cosval size store /sinval 0 store newpath 1 setlinejoin 1 setlinecap 0 cosval 10 div moveto 0 1 output pop intsin length 1 sub cycles mul cvi {/posn exch store /curpos posn speed mod store posn 10 div output curpos get 10 div 0.1 0 rlineto lineto } for 210 setwebtint 0.1 setlinewidth 1 setlinecap 1 setlinejoin stroke }store % make a new one from scratch /showfakesin { gsave cycles { -0.1 0 moveto 0.1 0 rlineto 0 1 intsin length 1 sub { /posnx exch store posnx 10 div 0.1 pop 0 add intsin posnx get 10 div lineto 0.1 0 rlineto } for 196 setwebtint stroke speed 10 div 0 translate } repeat grestore } store %% a real sinewave of amplitude sinsize %%%%%% /showrealsin {86 setwebtint 0 setlinewidth 0 0 moveto 0 1 speed cycles mul {/posn exch store posn 10 div % 0.05 add % adjust? posn 360 mul speed div sin sinsize mul 10 div lineto } for stroke} store %% a real cosine wave of amplitude size %%%%%% /showrealcos {86 setwebtint 0 setlinewidth 0 size 10 div moveto 0 1 speed cycles mul {/posn exch store posn 10 div posn 360 mul speed div dup 3 mul cos size mul 10 div /h3 exch store % huh? cos size mul 10 div % h3 .02 mul sub 1.02 mul % allows h3 addition, etc lineto } for stroke} store %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % revised formatting /showpeaks { 0 setlinewidth 5 setwebtint 0 0 moveto 48 0 rlineto stroke % pos sinsize 0 sinsize 10 div moveto 48 0 rlineto stroke % pos sinzsize 0 sinsize 10 div neg moveto 48 0 rlineto stroke % neg sinzsize 0 size 10 div moveto 48 0 rlineto stroke % pos size 0 size 10 div neg moveto 48 0 rlineto stroke % neg size } store /formatpage { makegrid showpeaks showfakecos showfakesin showrealcos showrealsin printtitle printharm printvalues printintsin printextcos showpage } store /makegrid { 50 50 10 setgrid 32 setwebtint 50 60 showgrid 1 15 translate} store %%%%%%%%%%%%%% print output %%%%%%%%%%%%%%%%% /printextcos { gsave 0 2 translate % show the signal /StoneSans-Bold findfont 1 scalefont setfont 0 setwebtint /vpos1 36 store 1 vpos1 moveto (Approximate Cosine Wave Output:) show /vpos1 vpos1 1.5 sub store 3 vpos1 moveto ([ ) show /wide speed 4 div cvi store 0 1 signal length 1 sub {/posn1 exch store signal posn1 get 20 string cvs show ( ) show posn1 1 add wide eq posn1 1 add wide 2 mul eq or posn1 1 add wide 3 mul eq or {/vpos1 vpos1 1.5 sub store 4 vpos1 moveto} if } for ( ]) show grestore } store /printintsin { gsave 0 3 translate % show the signal /StoneSans-Bold findfont 1 scalefont setfont 0 setwebtint /vpos1 26 store 1 vpos1 moveto (Approximate Internal Sine Wave:) show /vpos1 vpos1 1.5 sub store 3 vpos1 moveto ([ ) show /wide speed 4 div cvi store 0 1 intsin length 1 sub {/posn1 exch store intsin posn1 get 20 string cvs show ( ) show posn1 1 add wide eq posn1 1 add wide 2 mul eq or posn1 1 add wide 3 mul eq or {/vpos1 vpos1 1.5 sub store 4 vpos1 moveto} if } for ( ]) show grestore } store %%%%%%%%%%%%% print values %%%%%%%%%%%%% /printvalues { gsave 0 10 translate /StoneSans-Bold findfont 1 scalefont setfont 0 setwebtint 1 10 moveto (Cosine Amplitude "size" : ) size 20 string cvs mergestr show 1 8.5 moveto (Cosine Time Period "speed" : ) speed 20 string cvs mergestr show 1 7 moveto (Adjusted Sin Amplitude "sinsize" : ) sinsize 20 string cvs mergestr show 1 5.5 moveto (Cycles Displayed : ) cycles 1000 string cvs mergestr show grestore } store %%%%%%%%%%%%%% print title %%%%%%%%%%%% /printtitle {save /titsnap exch store currentdict /title known { /StoneSans-Bold findfont 2 scalefont setfont 2 42 moveto ( ) show title show } if grestore titsnap restore } store %%%%%%%%%%%% print harmonics %%%%%%%% /printharm {gsave 0 10 translate /StoneSans-Bold findfont 1 scalefont setfont 0 setwebtint 25 10 moveto (Third Harmonic: ) show intf3 100 mul 15 string cvs show ( percent.) show 25 8.5 moveto (Fifth Harmonic: ) show intf5 100 mul 15 string cvs show ( percent.) show 25 7 moveto (Seventh Harmonic: ) show intf7 100 mul 15 string cvs show ( percent.) show 25 5.5 moveto (Ninth Harmonic: ) show intf9 100 mul 15 string cvs show ( percent.) show 25 4 moveto ( THD 3 - 9 : ) show totaldist 1.0 mul 15 string cvs show ( percent.) show grestore } store % single data entered here [ [[1 2 3 4 5 6] (original triangle 18-24-8) ] [[1 2 3 4 5 6 7 8] (original triangle 32-32-8) ] [[1 2 3 4 5 6 7 8 9 10] (oriignal triangle 50-40-8) ] [[1 2 3 4 5 6 7 8 9 10 11 12] (original triangle 72-48-8) ] [[1 2 3 4 5 6 7 8 9 10 11 12 13 14] (original triangle 98-56-8) ] [[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] (triangle 128-64-8 out of range) ] [[1 2 3 4 5 6 7 8 8 8 8] (hard clip single 56-44-8) ] % .56 .75 [[1 2 3 4 5 6 7 7 8 8 8] (soft clip single 55-44-8) ] % .41 .48 % new singles [[1 2 3 4 5 6 6 6 6] (hard clip single 36-36-6) ] % .72 .99 [[1 2 3 4 5 5 6 6 6] (soft clip single 35-36-6) ] % .69 .69 [[1 2 3 4 5 6 7 8 9 10 10 10 10 10 ](hard clip single 85-56-10) ] % -.45 .73 [[1 2 3 4 5 6 7 8 9 9 10 10 10 10 ](soft clip single 84-56-10) ] % -.36 .48 [[1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 ](hard clip single 95-60-10)] % .44 .87 [[1 2 3 4 5 6 7 8 9 9 10 10 10 10 10 ](soft clip single 94-60-10) ] % .43 .66 ] findsinglepeaks (\n\nstarting finddouble) print [ [[1 2 3 4 5 6 6 6] (hard clip double 33-32-6) ] % 0.0! 0.5 BEST SO FAR [[1 2 3 4 5 6 7 7 7 7] (hard clip double 49-40-7)] % huh? .62 .94 [[1 2 3 4 5 6 6 7 7 7] (soft clip double 48-40-7)] % huh? .60 .64 [[1 2 3 4 5 6 7 8 8 8 8] (hard clip double 60-44-8)] % 0.0! .62 [[1 2 3 4 5 6 7 7 8 8 8] (soft clip double 60-44-8)] % 0.07 .25 VERY GOOD [[1 2 3 4 5 6 7 8 9 10 10 10 10 ] (hard clip double 95-52-10)] % -.9 1.01 [[1 2 3 4 5 6 7 8 9 10 10 10 10 10 ] (hard clip double 95-56-10)] % 0.0! .67 [[1 2 3 4 5 6 7 8 9 9 10 10 10 10 ] (soft clip double 94-56-10)] % 0.0! .67 [[1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12] (hard clip double 125-56-10)] % [[1 2 3 4 5 6 7 8 9 10 11 11 12 12 12 12] (soft clip double 124-56-10)] % 0.0! .67 [[1 2 3 4 5 6 7 8 9 10 11 12 12 12 12 12 12] (hard clip double 113-56-10)] % [[1 2 3 4 5 6 7 8 9 10 11 11 11 12 12 12 12 ] (soft clip double 112-56-10)] % 0.0! .67 ] finddoublepeaks % eof