%! % 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 23 amplitue 36 frequency 4 modified triangle % height sinewave usable by a low end microprocessor. Verified. % 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 23 store % height of sinewave /steps 36 store % steps per cycle /plothi 4 store % height of modified cosine triangle /adjustcos { % details here will vary with other amplitudes! dup 2 ge {1 sub} if dup -2 le {-1 sub} if dup 3 ge {1 sub} if dup -3 le {-1 sub} if dup 5 ge {pop 4} if dup -5 le {pop -4} if } store 10 250 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 /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 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 store /trim 1 store % should be one after debug 0 0 moveto 0 1 steps cycles mul {/pos exch store pos trim mul phase add pos 360 mul steps div sin plothi mul neg 2 copy == ( ) print == 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 gsave 0 5 moveto 0 setlinewidth 600 0 rlineto 5 setwebtint stroke grestore % red 5 gsave 0 10 moveto 0 setlinewidth 600 0 rlineto 5 setwebtint stroke grestore % red 10 %%%%%%%%%%%%%%%%%%%%%%% grid boxes %%%%%%%%%%%%%%%%%%%%% 4 1 12 {/ruleuh exch store % upper h grid 68 ruleuh moveto 20 0 rlineto 0 setwebtint 0 setlinewidth stroke } for 93 4 moveto % upper v grid 0 1 20 {/ruleuv exch store 68 ruleuv add 4 moveto 0 8 rlineto 0 setwebtint stroke } for showpage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Catalog: % 23-36-4: % filename matches amplitude % text matches data % no dc offset % cos fit all green % unity trim % 3 cosine pair adjustment % delta ( no previous ) % 39-40-6: % filename matches amplitude % text matches data % no dc offset % cos fit all green % unity trim % 3 cos pair adjustment % delta 40-36 = 14 % 55-44-8: % filename matches amplitude % text matches data % no dc offset % cos fit all green % unity trim % 2 cos pair adjustment % delta55-39 = 16 % 76-48-10: % filename matches amplitude % text matches data % no dc offset % cos fit all green % unity trim % 3 cos pair adjustment % delta 76-55 = 21 % 98-52-12: % filename matches amplitude % text matches data % no dc offset % cos fit all green % unity trim % 2 cos pair adjustment % delta 98-76 = 22 % 118-56-14 still has problems % EOF