%! % A modified efficient digital sinewave algorithm % ===================================== % Don Lancaster and Synergetics www.tinaja.com % Some ultra compact low end digital sinewave generators % were described in Column 10 of https://www.tinaja.com/glib/hackar1.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 example creates a 53 amplitue 44 frequency 8 modified triangle % height sinewave usable by a low end microprocessor. % This file is http://www.tinaja.com/psutils/nusine53.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/nusine53.pdf % It appears that dozens of similar low distortion sinewaves of % different amplitudes are possible. % 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 /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 {false} store /fatter10 { false} store /thingridlines {0} store %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%% adjusted sinewave %%%%%%%%%%%%% /sizegoal 53 store % height of sinewave /steps 44 store % steps per cycle /plothi 8 store % height of modified cosine triangle /adjustcos { % details here will vary with other amplitudes! dup 7 eq {pop 6} if dup -7 eq {pop -6} if dup 8 eq {pop 7} if dup -8 eq {pop -7} if dup 9 eq {pop 7} if dup -9 eq {pop -7} if dup 9 ge {pop 8 } if dup -9 le {pop -8 } if } store 10 150 translate 1 setlinewidth 1 setlinejoin 1 setlinecap %%%%%%%%%%%%%%%%%%%%% cos channel %%%%%%%%%%%%% % Calculate a 48 step low distortion digital sinewave… /size sizegoal def % set zero to peak size /speed 0 def % initialize speed /clip 8 def % initialize clip /cycles 6 store % number of full cycles 0 size moveto 1 1 steps cycles mul { % start a for loop /val exch store % save position /speed speed size 0 gt {-1}{+1} % start the algorithm ifelse add store /size size speed adjustcos add store % finish the algorithm % use your sinewave here 1 0 rlineto val size lineto % for actual % val size lineto % smoothed } for % complete loop 212 setwebtint 1 setlinewidth stroke %%%%%%%%%%%%%%%%%%%%%%% sin channel %%%%%%%%%%%%%%%%%%%%%%%%% -1 0 moveto /size sizegoal def % set zero to peak size /speed 0 def % initialize speed /clip 9 def % initialize clip /cycles 6 store % number of full cycles 1 1 steps cycles mul { % start a for loop /val exch store % save position /speed speed size 0 gt {-1}{+1} % start the algorithm ifelse add store /size size speed adjustcos add store % finish the algorithm % use your sinewave here 1 0 rlineto val speed adjustcos lineto % val speed adjustcos lineto } for % complete loop 30 setwebtint 1 setlinewidth stroke %%%%%%%%%%%%%% real comparison sinewave %%%%%%%%%%%%%%% /phase 0.5 store 0 0 moveto 0 1 steps cycles mul { dup phase add exch 360 mul steps div sin plothi mul neg lineto } for 0 setwebtint 0 setlinewidth stroke %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% gsave 0 0 moveto 0 setlinewidth 600 0 rlineto 212 setwebtint stroke grestore % baseline gsave 0 sizegoal moveto 0 setlinewidth 600 0 rlineto 212 setwebtint stroke grestore % baseline gsave 0 sizegoal neg moveto 0 setlinewidth 600 0 rlineto 212 setwebtint stroke grestore % baseline % validated results: % size 53 % steps per cycle 44 % sin plothi 8 % sin phase 0.5 % A sample of many other possible candidates... % 45-40-7 % 53-44-8 ( done here and verified ) % 61-48-9 % 69-52-10 % 77-56-11 % ... etc % code needs rewritten and retested for each showpage % EOF