STARTFONT 2.1 COMMENT COMMENT Copyright (c) 1999, Thomas A. Fine COMMENT COMMENT License to copy, modify, and distribute for both commercial and COMMENT non-commercial use is herby granted, provided this notice COMMENT is preserved. COMMENT COMMENT fine@head-cfa.harvard.edu COMMENT http://hea-www.harvard.edu/~fine/ COMMENT COMMENT Produced with bdfedit, a tcl/tk font editing program COMMENT written by Thomas A. Fine COMMENT FONT -atari-small SIZE 11 75 75 FONTBOUNDINGBOX 4 8 0 -1 STARTPROPERTIES 19 FONTNAME_REGISTRY "" FOUNDRY "Misc" FAMILY_NAME "Fixed" WEIGHT_NAME "Medium" SLANT "R" SETWIDTH_NAME "Normal" ADD_STYLE_NAME "" PIXEL_SIZE 8 POINT_SIZE 80 RESOLUTION_X 75 RESOLUTION_Y 75 SPACING "C" AVERAGE_WIDTH 50 CHARSET_REGISTRY "ISO8859" CHARSET_ENCODING "1" FONT_DESCENT 1 FONT_ASCENT 7 COPYRIGHT "Copyright 1999 by Thomas A. Fine" DEFAULT_CHAR 0 ENDPROPERTIES CHARS 128 STARTCHAR C000 ENCODING 0 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 00 00 00 ENDCHAR STARTCHAR C001 ENCODING 1 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 70 f0 70 20 00 00 ENDCHAR STARTCHAR C002 ENCODING 2 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 50 20 50 20 50 20 ENDCHAR STARTCHAR C003 ENCODING 3 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 50 50 70 50 50 30 10 10 ENDCHAR STARTCHAR C004 ENCODING 4 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP e0 80 c0 b0 a0 30 20 20 ENDCHAR STARTCHAR C005 ENCODING 5 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 60 80 60 00 30 20 30 20 ENDCHAR STARTCHAR C006 ENCODING 6 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 80 80 80 e0 30 20 30 20 ENDCHAR STARTCHAR C007 ENCODING 7 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 70 50 50 70 00 00 00 ENDCHAR STARTCHAR C010 ENCODING 8 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 70 20 00 70 00 00 ENDCHAR STARTCHAR C011 ENCODING 9 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 90 d0 b0 90 20 20 20 30 ENDCHAR STARTCHAR C012 ENCODING 10 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP a0 a0 a0 40 30 10 10 10 ENDCHAR STARTCHAR C013 ENCODING 11 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 e0 00 00 00 00 ENDCHAR STARTCHAR C014 ENCODING 12 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 e0 20 20 20 20 ENDCHAR STARTCHAR C015 ENCODING 13 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 30 20 20 20 20 ENDCHAR STARTCHAR C016 ENCODING 14 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 30 00 00 00 00 ENDCHAR STARTCHAR C017 ENCODING 15 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 f0 20 20 20 20 ENDCHAR STARTCHAR C020 ENCODING 16 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 70 00 00 00 00 00 00 ENDCHAR STARTCHAR C021 ENCODING 17 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 70 00 00 00 00 00 ENDCHAR STARTCHAR C022 ENCODING 18 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 70 00 00 00 00 ENDCHAR STARTCHAR C023 ENCODING 19 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 70 00 00 00 ENDCHAR STARTCHAR C024 ENCODING 20 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 70 00 00 ENDCHAR STARTCHAR C025 ENCODING 21 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 30 20 20 20 20 ENDCHAR STARTCHAR C026 ENCODING 22 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 e0 20 20 20 20 ENDCHAR STARTCHAR C027 ENCODING 23 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 20 f0 00 00 00 ENDCHAR STARTCHAR C030 ENCODING 24 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 f0 20 20 20 ENDCHAR STARTCHAR C031 ENCODING 25 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 20 20 20 20 20 20 20 ENDCHAR STARTCHAR C032 ENCODING 26 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 10 20 40 20 10 70 00 ENDCHAR STARTCHAR C033 ENCODING 27 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 20 10 20 40 70 00 ENDCHAR STARTCHAR C034 ENCODING 28 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 f0 50 50 50 50 00 00 ENDCHAR STARTCHAR C035 ENCODING 29 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 10 f0 20 f0 40 00 00 ENDCHAR STARTCHAR C036 ENCODING 30 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 30 40 e0 40 70 d0 40 00 ENDCHAR STARTCHAR C037 ENCODING 31 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 20 00 00 00 00 ENDCHAR STARTCHAR C040 ENCODING 32 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 00 00 00 ENDCHAR STARTCHAR ! ENCODING 33 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 40 40 40 00 40 00 ENDCHAR STARTCHAR " ENCODING 34 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 A0 A0 00 00 00 00 00 ENDCHAR STARTCHAR # ENCODING 35 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 E0 A0 A0 E0 a0 00 ENDCHAR STARTCHAR $ ENCODING 36 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 40 40 a0 40 20 a0 40 40 ENDCHAR STARTCHAR % ENCODING 37 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 20 40 40 80 a0 00 ENDCHAR STARTCHAR & ENCODING 38 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 40 a0 40 a0 a0 c0 60 00 ENDCHAR STARTCHAR ' ENCODING 39 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 40 00 00 00 00 00 ENDCHAR STARTCHAR ( ENCODING 40 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 40 40 40 40 20 00 ENDCHAR STARTCHAR ) ENCODING 41 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 40 40 40 40 80 00 ENDCHAR STARTCHAR * ENCODING 42 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 40 e0 40 a0 00 00 ENDCHAR STARTCHAR + ENCODING 43 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 40 e0 40 40 00 00 ENDCHAR STARTCHAR , ENCODING 44 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 40 40 80 ENDCHAR STARTCHAR - ENCODING 45 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 e0 00 00 00 00 ENDCHAR STARTCHAR . ENCODING 46 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 40 40 00 ENDCHAR STARTCHAR / ENCODING 47 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 20 40 40 80 80 00 ENDCHAR STARTCHAR 0 ENCODING 48 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 e0 a0 a0 40 00 ENDCHAR STARTCHAR 1 ENCODING 49 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 c0 40 40 40 e0 00 ENDCHAR STARTCHAR 2 ENCODING 50 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 20 40 80 e0 00 ENDCHAR STARTCHAR 3 ENCODING 51 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 20 40 20 a0 40 00 ENDCHAR STARTCHAR 4 ENCODING 52 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 60 a0 e0 20 20 00 ENDCHAR STARTCHAR 5 ENCODING 53 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 80 c0 20 a0 40 00 ENDCHAR STARTCHAR 6 ENCODING 54 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 60 80 c0 a0 a0 40 00 ENDCHAR STARTCHAR 7 ENCODING 55 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 20 20 40 40 40 00 ENDCHAR STARTCHAR 8 ENCODING 56 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 40 a0 a0 40 00 ENDCHAR STARTCHAR 9 ENCODING 57 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 a0 60 20 c0 00 ENDCHAR STARTCHAR : ENCODING 58 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 40 00 00 40 00 00 ENDCHAR STARTCHAR ; ENCODING 59 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 40 00 00 40 80 00 ENDCHAR STARTCHAR < ENCODING 60 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 20 40 80 40 20 00 ENDCHAR STARTCHAR = ENCODING 61 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 e0 00 e0 00 00 00 ENDCHAR STARTCHAR > ENCODING 62 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 80 40 20 40 80 00 ENDCHAR STARTCHAR ? ENCODING 63 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 20 40 00 40 00 ENDCHAR STARTCHAR @ ENCODING 64 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 a0 80 80 60 00 ENDCHAR STARTCHAR A ENCODING 65 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 a0 e0 a0 a0 00 ENDCHAR STARTCHAR B ENCODING 66 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 c0 a0 c0 a0 a0 c0 00 ENDCHAR STARTCHAR C ENCODING 67 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 80 80 a0 40 00 ENDCHAR STARTCHAR D ENCODING 68 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 c0 a0 a0 a0 a0 c0 00 ENDCHAR STARTCHAR E ENCODING 69 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 80 e0 80 80 e0 00 ENDCHAR STARTCHAR F ENCODING 70 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 80 e0 80 80 80 00 ENDCHAR STARTCHAR G ENCODING 71 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 80 a0 a0 40 00 ENDCHAR STARTCHAR H ENCODING 72 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 e0 a0 a0 a0 00 ENDCHAR STARTCHAR I ENCODING 73 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 40 40 40 40 e0 00 ENDCHAR STARTCHAR J ENCODING 74 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 20 20 20 a0 40 00 ENDCHAR STARTCHAR K ENCODING 75 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 c0 a0 a0 a0 00 ENDCHAR STARTCHAR L ENCODING 76 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 80 80 80 80 e0 00 ENDCHAR STARTCHAR M ENCODING 77 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 e0 a0 a0 a0 a0 00 ENDCHAR STARTCHAR N ENCODING 78 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 a0 e0 e0 a0 80 00 ENDCHAR STARTCHAR O ENCODING 79 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 a0 a0 a0 40 00 ENDCHAR STARTCHAR P ENCODING 80 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 c0 a0 a0 c0 80 80 00 ENDCHAR STARTCHAR Q ENCODING 81 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 a0 a0 c0 60 00 ENDCHAR STARTCHAR R ENCODING 82 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 c0 a0 a0 c0 a0 a0 00 ENDCHAR STARTCHAR S ENCODING 83 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 40 20 a0 40 00 ENDCHAR STARTCHAR T ENCODING 84 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 40 40 40 40 40 00 ENDCHAR STARTCHAR U ENCODING 85 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 a0 a0 a0 e0 00 ENDCHAR STARTCHAR V ENCODING 86 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 a0 a0 a0 40 00 ENDCHAR STARTCHAR W ENCODING 87 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 a0 a0 e0 a0 00 ENDCHAR STARTCHAR X ENCODING 88 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 40 a0 a0 a0 00 ENDCHAR STARTCHAR Y ENCODING 89 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 a0 a0 40 40 40 40 00 ENDCHAR STARTCHAR Z ENCODING 90 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 e0 20 40 40 80 e0 00 ENDCHAR STARTCHAR [ ENCODING 91 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 60 40 40 40 40 60 00 ENDCHAR STARTCHAR \ ENCODING 92 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 80 40 40 20 20 00 ENDCHAR STARTCHAR ] ENCODING 93 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 c0 40 40 40 40 c0 00 ENDCHAR STARTCHAR ^ ENCODING 94 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 a0 00 00 00 00 00 ENDCHAR STARTCHAR _ ENCODING 95 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 00 00 f0 ENDCHAR STARTCHAR ` ENCODING 96 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 40 00 00 00 00 00 ENDCHAR STARTCHAR a ENCODING 97 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 c0 20 60 a0 60 00 ENDCHAR STARTCHAR b ENCODING 98 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 80 c0 a0 a0 c0 00 ENDCHAR STARTCHAR c ENCODING 99 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 60 80 80 80 60 00 ENDCHAR STARTCHAR d ENCODING 100 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 20 60 a0 a0 60 00 ENDCHAR STARTCHAR e ENCODING 101 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 40 a0 e0 80 60 00 ENDCHAR STARTCHAR f ENCODING 102 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 40 e0 40 40 40 00 ENDCHAR STARTCHAR g ENCODING 103 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 60 a0 a0 60 20 c0 ENDCHAR STARTCHAR h ENCODING 104 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 80 c0 a0 a0 a0 00 ENDCHAR STARTCHAR i ENCODING 105 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 00 c0 40 40 e0 00 ENDCHAR STARTCHAR j ENCODING 106 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 20 00 60 20 20 20 c0 ENDCHAR STARTCHAR k ENCODING 107 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 80 80 a0 c0 a0 a0 00 ENDCHAR STARTCHAR l ENCODING 108 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 40 40 40 40 40 00 ENDCHAR STARTCHAR m ENCODING 109 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 e0 a0 a0 a0 00 ENDCHAR STARTCHAR n ENCODING 110 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 c0 a0 a0 a0 a0 00 ENDCHAR STARTCHAR o ENCODING 111 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 40 a0 a0 a0 40 00 ENDCHAR STARTCHAR p ENCODING 112 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 c0 a0 a0 c0 80 80 ENDCHAR STARTCHAR q ENCODING 113 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 60 a0 a0 60 20 20 ENDCHAR STARTCHAR r ENCODING 114 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 60 80 80 80 80 00 ENDCHAR STARTCHAR s ENCODING 115 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 60 80 40 20 c0 00 ENDCHAR STARTCHAR t ENCODING 116 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 40 40 e0 40 40 40 00 ENDCHAR STARTCHAR u ENCODING 117 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 a0 a0 a0 e0 00 ENDCHAR STARTCHAR v ENCODING 118 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 a0 a0 a0 40 00 ENDCHAR STARTCHAR w ENCODING 119 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 a0 a0 e0 a0 00 ENDCHAR STARTCHAR x ENCODING 120 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 a0 40 a0 a0 00 ENDCHAR STARTCHAR y ENCODING 121 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 a0 a0 a0 60 20 c0 ENDCHAR STARTCHAR z ENCODING 122 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 e0 20 40 80 e0 00 ENDCHAR STARTCHAR { ENCODING 123 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 20 40 40 80 40 40 20 00 ENDCHAR STARTCHAR | ENCODING 124 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 40 40 40 00 40 40 40 00 ENDCHAR STARTCHAR } ENCODING 125 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 80 40 40 20 40 40 80 00 ENDCHAR STARTCHAR ~ ENCODING 126 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 c0 60 00 00 00 00 ENDCHAR STARTCHAR C177 ENCODING 127 SWIDTH 1 0 DWIDTH 4 0 BBX 4 8 0 -1 BITMAP 00 00 00 00 00 00 00 00 ENDCHAR ENDFONT 07' href='#n307'>307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

/*  sig~ and line~ control-to-signal converters;
    snapshot~ signal-to-control converter.
*/

#include "m_pd.h"
#include "math.h"

/* -------------------------- sig~ ------------------------------ */
static t_class *sig_tilde_class;

typedef struct _sig
{
    t_object x_obj;
    float x_f;
} t_sig;

static t_int *sig_tilde_perform(t_int *w)
{
    t_float f = *(t_float *)(w[1]);
    t_float *out = (t_float *)(w[2]);
    int n = (int)(w[3]);
    while (n--)
    	*out++ = f; 
    return (w+4);
}

static t_int *sig_tilde_perf8(t_int *w)
{
    t_float f = *(t_float *)(w[1]);
    t_float *out = (t_float *)(w[2]);
    int n = (int)(w[3]);
    
    for (; n; n -= 8, out += 8)
    {
    	out[0] = f;
    	out[1] = f;
    	out[2] = f;
    	out[3] = f;
    	out[4] = f;
    	out[5] = f;
    	out[6] = f;
    	out[7] = f;
    }
    return (w+4);
}

void dsp_add_scalarcopy(t_sample *in, t_sample *out, int n)
{
    if (n&7)
    	dsp_add(sig_tilde_perform, 3, in, out, n);
    else	
    	dsp_add(sig_tilde_perf8, 3, in, out, n);
}

static void sig_tilde_float(t_sig *x, t_float f)
{
    x->x_f = f;
}

static void sig_tilde_dsp(t_sig *x, t_signal **sp)
{
    dsp_add(sig_tilde_perform, 3, &x->x_f, sp[0]->s_vec, sp[0]->s_n);
}

static void *sig_tilde_new(t_floatarg f)
{
    t_sig *x = (t_sig *)pd_new(sig_tilde_class);
    x->x_f = f;
    outlet_new(&x->x_obj, gensym("signal"));
    return (x);
}

static void sig_tilde_setup(void)
{
    sig_tilde_class = class_new(gensym("sig~"), (t_newmethod)sig_tilde_new, 0,
    	sizeof(t_sig), 0, A_DEFFLOAT, 0);
    class_addfloat(sig_tilde_class, (t_method)sig_tilde_float);
    class_addmethod(sig_tilde_class, (t_method)sig_tilde_dsp, gensym("dsp"), 0);
}


#ifndef FIXEDPOINT

/* -------------------------- line~ ------------------------------ */
static t_class *line_tilde_class;

typedef struct _line
{
    t_object x_obj;
    float x_target;
    float x_value;
    float x_biginc;
    float x_inc;
    float x_1overn;
    float x_dspticktomsec;
    float x_inletvalue;
    float x_inletwas;
    int x_ticksleft;
    int x_retarget;
} t_line;

static t_int *line_tilde_perform(t_int *w)
{
    t_line *x = (t_line *)(w[1]);
    t_float *out = (t_float *)(w[2]);
    int n = (int)(w[3]);
    float f = x->x_value;

    if (PD_BIGORSMALL(f))
	    x->x_value = f = 0;
    if (x->x_retarget)
    {
    	int nticks = x->x_inletwas * x->x_dspticktomsec;
    	if (!nticks) nticks = 1;
    	x->x_ticksleft = nticks;
    	x->x_biginc = (x->x_target - x->x_value)/(float)nticks;
    	x->x_inc = x->x_1overn * x->x_biginc;
    	x->x_retarget = 0;
    }
    if (x->x_ticksleft)
    {
    	float f = x->x_value;
    	while (n--) *out++ = f, f += x->x_inc;
    	x->x_value += x->x_biginc;
    	x->x_ticksleft--;
    }
    else
    {
    	x->x_value = x->x_target;
    	while (n--) *out++ = x->x_value;
    }
    return (w+4);
}

static void line_tilde_float(t_line *x, t_float f)
{
    if (x->x_inletvalue <= 0)
    {
    	x->x_target = x->x_value = f;
    	x->x_ticksleft = x->x_retarget = 0;
    }
    else
    {
    	x->x_target = f;
    	x->x_retarget = 1;
    	x->x_inletwas = x->x_inletvalue;
    	x->x_inletvalue = 0;
    }
}

static void line_tilde_stop(t_line *x)
{
    x->x_target = x->x_value;
    x->x_ticksleft = x->x_retarget = 0;
}

static void line_tilde_dsp(t_line *x, t_signal **sp)
{
    dsp_add(line_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
    x->x_1overn = 1./sp[0]->s_n;
    x->x_dspticktomsec = sp[0]->s_sr / (1000 * sp[0]->s_n);
}

static void *line_tilde_new(void)
{
    t_line *x = (t_line *)pd_new(line_tilde_class);
    outlet_new(&x->x_obj, gensym("signal"));
    floatinlet_new(&x->x_obj, &x->x_inletvalue);
    x->x_ticksleft = x->x_retarget = 0;
    x->x_value = x->x_target = x->x_inletvalue = x->x_inletwas = 0;
    return (x);
}

static void line_tilde_setup(void)
{
    line_tilde_class = class_new(gensym("line~"), line_tilde_new, 0,
    	sizeof(t_line), 0, 0);
    class_addfloat(line_tilde_class, (t_method)line_tilde_float);
    class_addmethod(line_tilde_class, (t_method)line_tilde_dsp,
    	gensym("dsp"), 0);
    class_addmethod(line_tilde_class, (t_method)line_tilde_stop,
    	gensym("stop"), 0);
}

/* -------------------------- vline~ ------------------------------ */
static t_class *vline_tilde_class;

typedef struct _vseg
{
    double s_targettime;
    double s_starttime;
    float s_target;
    struct _vseg *s_next;
} t_vseg;

typedef struct _vline
{
    t_object x_obj;
    double x_value;
    double x_inc;
    double x_referencetime;
    double x_samppermsec;
    double x_msecpersamp;
    double x_targettime;
    float x_target;
    float x_inlet1;
    float x_inlet2;
    t_vseg *x_list;
} t_vline;

static t_int *vline_tilde_perform(t_int *w)
{
    t_vline *x = (t_vline *)(w[1]);
    t_float *out = (t_float *)(w[2]);
    int n = (int)(w[3]), i;
    double f = x->x_value;
    double inc = x->x_inc;
    double msecpersamp = x->x_msecpersamp;
    double samppermsec = x->x_samppermsec;
    double timenow = clock_gettimesince(x->x_referencetime) - n * msecpersamp;
    t_vseg *s = x->x_list;
    for (i = 0; i < n; i++)
    {
    	double timenext = timenow + msecpersamp;
    checknext:
	if (s)
	{
	    /* has starttime elapsed?  If so update value and increment */
	    if (s->s_starttime < timenext)
	    {
		if (x->x_targettime <= timenext)
		    f = x->x_target, inc = 0;
	    	    /* if zero-length segment bash output value */
	    	if (s->s_targettime <= s->s_starttime)
		{
		    f = s->s_target;
		    inc = 0;
		}
		else
		{
		    double incpermsec = (s->s_target - f)/
		    	(s->s_targettime - s->s_starttime);
		    f = f + incpermsec * (timenext - s->s_starttime);
		    inc = incpermsec * msecpersamp;
		}
    	    	x->x_inc = inc;
		x->x_target = s->s_target;
		x->x_targettime = s->s_targettime;
		x->x_list = s->s_next;
		t_freebytes(s, sizeof(*s));
		s = x->x_list;
		goto checknext;
	    }
	}
	if (x->x_targettime <= timenext)
	    f = x->x_target, inc = x->x_inc = 0, x->x_targettime = 1e20;
	*out++ = f;
	f = f + inc;
	timenow = timenext;
    }
    x->x_value = f;
    return (w+4);
}

static void vline_tilde_stop(t_vline *x)
{
    t_vseg *s1, *s2;
    for (s1 = x->x_list; s1; s1 = s2)
    	s2 = s1->s_next, t_freebytes(s1, sizeof(*s1));
    x->x_list = 0;
    x->x_inc = 0;
    x->x_inlet1 = x->x_inlet2 = 0;
    x->x_target = x->x_value;
    x->x_targettime = 1e20;
}

static void vline_tilde_float(t_vline *x, t_float f)
{
    double timenow = clock_gettimesince(x->x_referencetime);
    float inlet1 = (x->x_inlet1 < 0 ? 0 : x->x_inlet1);
    float inlet2 = x->x_inlet2;
    double starttime = timenow + inlet2;
    t_vseg *s1, *s2, *deletefrom = 0, *snew;
    if (PD_BIGORSMALL(f))
	f = 0;

    	/* negative delay input means stop and jump immediately to new value */
    if (inlet2 < 0)
    {
	x->x_value = f;
    	vline_tilde_stop(x);
	return;
    }
    snew = (t_vseg *)t_getbytes(sizeof(*snew));
    	/* check if we supplant the first item in the list.  We supplant
	an item by having an earlier starttime, or an equal starttime unless
	the equal one was instantaneous and the new one isn't (in which case
	we'll do a jump-and-slide starting at that time.) */
    if (!x->x_list || x->x_list->s_starttime > starttime ||
    	(x->x_list->s_starttime == starttime &&
	    (x->x_list->s_targettime > x->x_list->s_starttime || inlet1 <= 0)))
    {
    	deletefrom = x->x_list;
	x->x_list = snew;
    }
    else
    {
    	for (s1 = x->x_list; s2 = s1->s_next; s1 = s2)
	{
    	    if (s2->s_starttime > starttime ||
    		(s2->s_starttime == starttime &&
		    (s2->s_targettime > s2->s_starttime || inlet1 <= 0)))
	    {
    		deletefrom = s2;
		s1->s_next = snew;
		goto didit;
	    }
	}
	s1->s_next = snew;
	deletefrom = 0;
    didit: ;
    }
    while (deletefrom)
    {
    	s1 = deletefrom->s_next;
	t_freebytes(deletefrom, sizeof(*deletefrom));
	deletefrom = s1;
    }
    snew->s_next = 0;
    snew->s_target = f;
    snew->s_starttime = starttime;
    snew->s_targettime = starttime + inlet1;
    x->x_inlet1 = x->x_inlet2 = 0;
}

static void vline_tilde_dsp(t_vline *x, t_signal **sp)
{
    dsp_add(vline_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
    x->x_samppermsec = ((double)(sp[0]->s_sr)) / 1000;
    x->x_msecpersamp = ((double)1000) / sp[0]->s_sr;
}

static void *vline_tilde_new(void)
{
    t_vline *x = (t_vline *)pd_new(vline_tilde_class);
    outlet_new(&x->x_obj, gensym("signal"));
    floatinlet_new(&x->x_obj, &x->x_inlet1);
    floatinlet_new(&x->x_obj, &x->x_inlet2);
    x->x_inlet1 = x->x_inlet2 = 0;
    x->x_value = x->x_inc = 0;
    x->x_referencetime = clock_getlogicaltime();
    x->x_list = 0;
    x->x_samppermsec = 0;
    x->x_targettime = 1e20;
    return (x);
}

static void vline_tilde_setup(void)
{
    vline_tilde_class = class_new(gensym("vline~"), vline_tilde_new, 
    	(t_method)vline_tilde_stop, sizeof(t_vline), 0, 0);
    class_addfloat(vline_tilde_class, (t_method)vline_tilde_float);
    class_addmethod(vline_tilde_class, (t_method)vline_tilde_dsp,
    	gensym("dsp"), 0);
    class_addmethod(vline_tilde_class, (t_method)vline_tilde_stop,
    	gensym("stop"), 0);
}

/* -------------------------- snapshot~ ------------------------------ */
static t_class *snapshot_tilde_class;

typedef struct _snapshot
{
    t_object x_obj;
    t_sample x_value;
    float x_f;
} t_snapshot;

static void *snapshot_tilde_new(void)
{
    t_snapshot *x = (t_snapshot *)pd_new(snapshot_tilde_class);
    x->x_value = 0;
    outlet_new(&x->x_obj, &s_float);
    x->x_f = 0;
    return (x);
}

static t_int *snapshot_tilde_perform(t_int *w)
{
    t_float *in = (t_float *)(w[1]);
    t_float *out = (t_float *)(w[2]);
    *out = *in;
    return (w+3);
}

static void snapshot_tilde_dsp(t_snapshot *x, t_signal **sp)
{
    dsp_add(snapshot_tilde_perform, 2, sp[0]->s_vec + (sp[0]->s_n-1),
    	&x->x_value);
}

static void snapshot_tilde_bang(t_snapshot *x)
{
    outlet_float(x->x_obj.ob_outlet, x->x_value);
}

static void snapshot_tilde_set(t_snapshot *x, t_floatarg f)
{
    x->x_value = f;
}

static void snapshot_tilde_setup(void)
{
    snapshot_tilde_class = class_new(gensym("snapshot~"), snapshot_tilde_new, 0,
    	sizeof(t_snapshot), 0, 0);
    CLASS_MAINSIGNALIN(snapshot_tilde_class, t_snapshot, x_f);
    class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_dsp,
    	gensym("dsp"), 0);
    class_addmethod(snapshot_tilde_class, (t_method)snapshot_tilde_set,
    	gensym("set"), A_DEFFLOAT, 0);
    class_addbang(snapshot_tilde_class, snapshot_tilde_bang);
}

/* -------------------------- vsnapshot~ ------------------------------ */
static t_class *vsnapshot_tilde_class;

typedef struct _vsnapshot
{
    t_object x_obj;
    int x_n;
    int x_gotone;
    t_sample *x_vec;
    float x_f;
    float x_sampspermsec;
    double x_time;
} t_vsnapshot;

static void *vsnapshot_tilde_new(void)
{
    t_vsnapshot *x = (t_vsnapshot *)pd_new(vsnapshot_tilde_class);
    outlet_new(&x->x_obj, &s_float);
    x->x_f = 0;
    x->x_n = 0;
    x->x_vec = 0;
    x->x_gotone = 0;
    return (x);
}

static t_int *vsnapshot_tilde_perform(t_int *w)
{
    t_float *in = (t_float *)(w[1]);
    t_vsnapshot *x = (t_vsnapshot *)(w[2]);
    t_float *out = x->x_vec;
    int n = x->x_n, i;
    for (i = 0; i < n; i++)
    	out[i] = in[i];
    x->x_time = clock_getlogicaltime();
    x->x_gotone = 1;
    return (w+3);
}

static void vsnapshot_tilde_dsp(t_vsnapshot *x, t_signal **sp)
{
    int n = sp[0]->s_n;
    if (n != x->x_n)
    {
    	if (x->x_vec)
	    t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
	x->x_vec = (t_sample *)getbytes(n * sizeof(t_sample));
    	x->x_gotone = 0;
	x->x_n = n;
    }
    x->x_sampspermsec = sp[0]->s_sr / 1000;
    dsp_add(vsnapshot_tilde_perform, 2, sp[0]->s_vec, x);
}

static void vsnapshot_tilde_bang(t_vsnapshot *x)
{
    float val;
    if (x->x_gotone)
    {
    	int indx = clock_gettimesince(x->x_time) * x->x_sampspermsec;
	if (indx < 0)
	    indx = 0;
    	else if (indx >= x->x_n)
	    indx = x->x_n - 1;
	val = x->x_vec[indx];
    }
    else val = 0;
    outlet_float(x->x_obj.ob_outlet, val);
}

static void vsnapshot_tilde_ff(t_vsnapshot *x)
{
    if (x->x_vec)
	t_freebytes(x->x_vec, x->x_n * sizeof(t_sample));
}

static void vsnapshot_tilde_setup(void)
{
    vsnapshot_tilde_class = class_new(gensym("vsnapshot~"),
    	vsnapshot_tilde_new, (t_method)vsnapshot_tilde_ff,
    	sizeof(t_vsnapshot), 0, 0);
    CLASS_MAINSIGNALIN(vsnapshot_tilde_class, t_vsnapshot, x_f);
    class_addmethod(vsnapshot_tilde_class, (t_method)vsnapshot_tilde_dsp, gensym("dsp"), 0);
    class_addbang(vsnapshot_tilde_class, vsnapshot_tilde_bang);
}


/* ---------------- env~ - simple envelope follower. ----------------- */

#define MAXOVERLAP 10
#define MAXVSTAKEN 64

typedef struct sigenv
{
    t_object x_obj; 	    	    /* header */
    void *x_outlet;		    /* a "float" outlet */
    void *x_clock;		    /* a "clock" object */
    float *x_buf;		    /* a Hanning window */
    int x_phase;		    /* number of points since last output */
    int x_period;		    /* requested period of output */
    int x_realperiod;		    /* period rounded up to vecsize multiple */
    int x_npoints;		    /* analysis window size in samples */
    float x_result;		    /* result to output */
    float x_sumbuf[MAXOVERLAP];	    /* summing buffer */
    float x_f;
} t_sigenv;

t_class *env_tilde_class;
static void env_tilde_tick(t_sigenv *x);

static void *env_tilde_new(t_floatarg fnpoints, t_floatarg fperiod)
{
    int npoints = fnpoints;
    int period = fperiod;
    t_sigenv *x;
    float *buf;
    int i;

    if (npoints < 1) npoints = 1024;
    if (period < 1) period = npoints/2;
    if (period < npoints / MAXOVERLAP + 1)
	period = npoints / MAXOVERLAP + 1;
    if (!(buf = getbytes(sizeof(float) * (npoints + MAXVSTAKEN))))
    {
	error("env: couldn't allocate buffer");
	return (0);
    }
    x = (t_sigenv *)pd_new(env_tilde_class);
    x->x_buf = buf;
    x->x_npoints = npoints;
    x->x_phase = 0;
    x->x_period = period;
    for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
    for (i = 0; i < npoints; i++)
	buf[i] = (1. - cos((2 * 3.14159 * i) / npoints))/npoints;
    for (; i < npoints+MAXVSTAKEN; i++) buf[i] = 0;
    x->x_clock = clock_new(x, (t_method)env_tilde_tick);
    x->x_outlet = outlet_new(&x->x_obj, gensym("float"));
    x->x_f = 0;
    return (x);
}

static t_int *env_tilde_perform(t_int *w)
{
    t_sigenv *x = (t_sigenv *)(w[1]);
    t_float *in = (t_float *)(w[2]);
    int n = (int)(w[3]);
    int count;
    float *sump; 
    in += n;
    for (count = x->x_phase, sump = x->x_sumbuf;
	count < x->x_npoints; count += x->x_realperiod, sump++)
    {
	float *hp = x->x_buf + count;
	float *fp = in;
	float sum = *sump;
	int i;
	
	for (i = 0; i < n; i++)
	{
	    fp--;
	    sum += *hp++ * (*fp * *fp);
	}
	*sump = sum;
    }
    sump[0] = 0;
    x->x_phase -= n;
    if (x->x_phase < 0)
    {
	x->x_result = x->x_sumbuf[0];
	for (count = x->x_realperiod, sump = x->x_sumbuf;
	    count < x->x_npoints; count += x->x_realperiod, sump++)
		sump[0] = sump[1];
	sump[0] = 0;
	x->x_phase = x->x_realperiod - n;
	clock_delay(x->x_clock, 0L);
    }
    return (w+4);
}

static void env_tilde_dsp(t_sigenv *x, t_signal **sp)
{
    if (x->x_period % sp[0]->s_n) x->x_realperiod =
	x->x_period + sp[0]->s_n - (x->x_period % sp[0]->s_n);
    else x->x_realperiod = x->x_period;
    dsp_add(env_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
    if (sp[0]->s_n > MAXVSTAKEN) bug("env_tilde_dsp");
}

static void env_tilde_tick(t_sigenv *x)	/* callback function for the clock */
{
    outlet_float(x->x_outlet, powtodb(x->x_result));
}

static void env_tilde_ff(t_sigenv *x)		/* cleanup on free */
{
    clock_free(x->x_clock);
    freebytes(x->x_buf, (x->x_npoints + MAXVSTAKEN) * sizeof(float));
}


void env_tilde_setup(void )
{
    env_tilde_class = class_new(gensym("env~"), (t_newmethod)env_tilde_new,
    	(t_method)env_tilde_ff, sizeof(t_sigenv), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(env_tilde_class, t_sigenv, x_f);
    class_addmethod(env_tilde_class, (t_method)env_tilde_dsp, gensym("dsp"), 0);
}

/* --------------------- threshold~ ----------------------------- */

static t_class *threshold_tilde_class;

typedef struct _threshold_tilde
{
    t_object x_obj;
    t_outlet *x_outlet1;    	/* bang out for high thresh */
    t_outlet *x_outlet2;    	/* bang out for low thresh */
    t_clock *x_clock;	    	/* wakeup for message output */
    float x_f;	    	    	/* scalar inlet */
    int x_state;    		/* 1 = high, 0 = low */
    float x_hithresh;	    	/* value of high threshold */
    float x_lothresh;	    	/* value of low threshold */
    float x_deadwait;	    	/* msec remaining in dead period */
    float x_msecpertick;	/* msec per DSP tick */
    float x_hideadtime;	    	/* hi dead time in msec */
    float x_lodeadtime;	    	/* lo dead time in msec */
} t_threshold_tilde;

static void threshold_tilde_tick(t_threshold_tilde *x);
static void threshold_tilde_set(t_threshold_tilde *x,
    t_floatarg hithresh, t_floatarg hideadtime,
    t_floatarg lothresh, t_floatarg lodeadtime);

static t_threshold_tilde *threshold_tilde_new(t_floatarg hithresh,
    t_floatarg hideadtime, t_floatarg lothresh, t_floatarg lodeadtime)
{
    t_threshold_tilde *x = (t_threshold_tilde *)
    	pd_new(threshold_tilde_class);
    x->x_state = 0;		/* low state */
    x->x_deadwait = 0;		/* no dead time */
    x->x_clock = clock_new(x, (t_method)threshold_tilde_tick);
    x->x_outlet1 = outlet_new(&x->x_obj, &s_bang);
    x->x_outlet2 = outlet_new(&x->x_obj, &s_bang);
    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
    x->x_msecpertick = 0.;
    x->x_f = 0;
    threshold_tilde_set(x, hithresh, hideadtime, lothresh, lodeadtime);
    return (x);
}

    /* "set" message to specify thresholds and dead times */
static void threshold_tilde_set(t_threshold_tilde *x,
    t_floatarg hithresh, t_floatarg hideadtime,
    t_floatarg lothresh, t_floatarg lodeadtime)
{
    if (lothresh > hithresh)
    	lothresh = hithresh;
    x->x_hithresh = hithresh;
    x->x_hideadtime = hideadtime;
    x->x_lothresh = lothresh;
    x->x_lodeadtime = lodeadtime;
}

    /* number in inlet sets state -- note incompatible with JMAX which used
    "int" message for this, impossible here because of auto signal conversion */
static void threshold_tilde_ft1(t_threshold_tilde *x, t_floatarg f)
{
    x->x_state = (f != 0);
    x->x_deadwait = 0;
}

static void threshold_tilde_tick(t_threshold_tilde *x)	
{
    if (x->x_state)
    	outlet_bang(x->x_outlet1);
    else outlet_bang(x->x_outlet2);
}

static t_int *threshold_tilde_perform(t_int *w)
{
    float *in1 = (float *)(w[1]);
    t_threshold_tilde *x = (t_threshold_tilde *)(w[2]);
    int n = (t_int)(w[3]);
    if (x->x_deadwait > 0)
    	x->x_deadwait -= x->x_msecpertick;
    else if (x->x_state)
    {
    	    /* we're high; look for low sample */
    	for (; n--; in1++)
	{
	    if (*in1 < x->x_lothresh)
	    {
		clock_delay(x->x_clock, 0L);
		x->x_state = 0;
		x->x_deadwait = x->x_lodeadtime;
		goto done;
	    }
    	}
    }
    else
    {
    	    /* we're low; look for high sample */
    	for (; n--; in1++)
	{
	    if (*in1 >= x->x_hithresh)
	    {
		clock_delay(x->x_clock, 0L);
		x->x_state = 1;
		x->x_deadwait = x->x_hideadtime;
		goto done;
	    }
    	}
    }
done:
    return (w+4);
}

void threshold_tilde_dsp(t_threshold_tilde *x, t_signal **sp)
{
    x->x_msecpertick = 1000. * sp[0]->s_n / sp[0]->s_sr;
    dsp_add(threshold_tilde_perform, 3, sp[0]->s_vec, x, sp[0]->s_n);
}

static void threshold_tilde_ff(t_threshold_tilde *x)
{
    clock_free(x->x_clock);
}

static void threshold_tilde_setup( void)
{
    threshold_tilde_class = class_new(gensym("threshold~"),
    	(t_newmethod)threshold_tilde_new, (t_method)threshold_tilde_ff,
	sizeof(t_threshold_tilde), 0,
	    A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0);
    CLASS_MAINSIGNALIN(threshold_tilde_class, t_threshold_tilde, x_f);
    class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_set,
    	gensym("set"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
    class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_ft1,
    	gensym("ft1"), A_FLOAT, 0);
    class_addmethod(threshold_tilde_class, (t_method)threshold_tilde_dsp,
    	gensym("dsp"), 0);
}

/* ------------------------ global setup routine ------------------------- */

void d_ctl_setup(void)
{
    sig_tilde_setup();
    line_tilde_setup();
    vline_tilde_setup();
    snapshot_tilde_setup();
    vsnapshot_tilde_setup();
    env_tilde_setup();
    threshold_tilde_setup();
}

#endif