computerscare-vcv-modules

computerscare modules for VCV Rack
Log | Files | Refs

commit 445fbdcf9bb25cdd2408a49990041e54b64ba109
parent e68deab0b08b49db1d3eddee829208e6f8dd3f69
Author: Adam M <[email protected]>
Date:   Thu, 31 Dec 2020 16:46:05 -0600

Sync and clock inputs for Blank

Diffstat:
Ares/blank-clock-mode-frame.svg | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/blank-clock-mode-scan.svg | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ares/blank-clock-mode-sync.svg | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/ComputerscareBlank.cpp | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Msrc/ComputerscareBlankExpander.cpp | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/animatedGif.hpp | 11++++++++++-
6 files changed, 557 insertions(+), 61 deletions(-)

diff --git a/res/blank-clock-mode-frame.svg b/res/blank-clock-mode-frame.svg @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="10mm" + height="5mm" + viewBox="0 0 10 5" + version="1.1" + id="svg890" + inkscape:version="1.0.1 (c497b03c, 2020-09-10)" + sodipodi:docname="blank-clock-mode-frame.svg"> + <defs + id="defs884" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="7.919596" + inkscape:cx="21.273995" + inkscape:cy="-3.2245175" + inkscape:document-units="mm" + inkscape:current-layer="text1460" + showgrid="false" + units="mm" + inkscape:window-width="1440" + inkscape:window-height="855" + inkscape:window-x="0" + inkscape:window-y="23" + inkscape:window-maximized="1" + inkscape:snap-global="false" + inkscape:document-rotation="0" /> + <metadata + id="metadata887"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-292)"> + <g + aria-label="rst" + style="font-style:normal;font-weight:normal;font-size:6.29599571px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15739989" + id="text1460"> + <rect + style="fill:#dedede;fill-opacity:1;stroke:#000000;stroke-width:0.0405524;stroke-opacity:1" + id="rect2390" + width="8.3529882" + height="3.7808547" + x="0.21206512" + y="292.08575" /> + <path + style="fill:#adadad;fill-opacity:1;stroke:#000000;stroke-width:0.123364;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.6010514,292.15224 0.9606512,0.5907 0.04803,4.14751 -1.0086822,-1.00279 z" + id="path2394" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#848484;fill-opacity:1;stroke:#000000;stroke-width:0.151541;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0.30028176,295.89921 0.60080928,0.7815 8.62675976,0.15764 -0.9800881,-1.01884 z" + id="path2396" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <g + aria-label="frame" + transform="matrix(0.76262226,0,0,1.1336577,0.34345586,13.029411)" + id="text1621" + style="font-style:normal;font-weight:normal;font-size:3.56971px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0140468"> + <path + d="m 1.344079,246.7035 -0.01743,0.003 q -0.054034,-0.007 -0.1411848,-0.009 -0.087151,-0.004 -0.153386,0.007 -0.21090568,0.0332 -0.30677191,0.14233 -0.0941232,0.1072 -0.0941232,0.3512 v 0.0662 l 0.59088431,-0.0929 v 0.27539 l -0.58042649,0.0913 v 1.67156 l -0.32768823,0.0515 v -1.67156 l -0.22136385,0.0348 v -0.27539 l 0.22136385,-0.0348 v -0.0645 q 0,-0.34686 0.17255923,-0.55875 0.17255922,-0.21363 0.49850442,-0.26488 0.10981037,-0.0173 0.19696157,-0.0205 0.088894,-0.003 0.1621011,-10e-4 z" + style="stroke-width:0.0140468" + id="path1728" /> + <path + d="m 2.7663853,247.49925 h -0.01743 q -0.073207,-0.0174 -0.1429278,-0.0244 -0.067978,-0.009 -0.1621011,-0.009 -0.1516429,0 -0.2928278,0.068 -0.1411848,0.0662 -0.2719115,0.17256 v 1.38221 H 1.5514986 v -1.94695 h 0.3276882 v 0.2876 q 0.1952186,-0.15688 0.3433755,-0.22137 0.1498999,-0.0662 0.3050289,-0.0662 0.085408,0 0.1237546,0.005 0.038346,0.003 0.1150395,0.0157 z" + style="stroke-width:0.0140468" + id="path1730" /> + <path + d="m 4.5913297,248.58789 -0.3259453,0.0512 v -0.20742 q -0.043576,0.0365 -0.1185255,0.10233 -0.073207,0.0638 -0.1429278,0.10617 -0.081922,0.053 -0.1882464,0.0958 -0.1063244,0.0446 -0.2492523,0.0671 -0.2631964,0.0414 -0.4462137,-0.10416 -0.1830174,-0.14552 -0.1830174,-0.41569 0,-0.22136 0.094123,-0.37212 0.095866,-0.15277 0.2719115,-0.25888 0.1777883,-0.10635 0.4270406,-0.17347 0.2492522,-0.0671 0.5351078,-0.12592 v -0.0505 q 0,-0.11155 -0.04009,-0.17846 -0.038346,-0.0672 -0.1115534,-0.0975 -0.069721,-0.0291 -0.1673302,-0.0277 -0.097609,0.001 -0.2039336,0.0182 -0.1289837,0.0203 -0.2875987,0.0801 -0.158615,0.058 -0.3276882,0.14912 l -0.01743,0.003 v -0.33292 q 0.095866,-0.0413 0.2771405,-0.10107 0.1812744,-0.0599 0.3573196,-0.0876 0.2056767,-0.0323 0.3573196,-0.0213 0.153386,0.009 0.2649395,0.0734 0.1098104,0.0629 0.1673301,0.18112 0.05752,0.11819 0.05752,0.30644 z m -0.3259453,-0.42808 v -0.54208 q -0.1498999,0.0326 -0.3538335,0.0818 -0.2021906,0.0492 -0.3207161,0.10093 -0.1411849,0.0623 -0.228336,0.16139 -0.087151,0.0974 -0.087151,0.24553 0,0.16733 0.1010953,0.23684 0.1010953,0.0678 0.308515,0.0352 0.1725592,-0.0271 0.315487,-0.1158 0.1429279,-0.0905 0.2649394,-0.20375 z" + style="stroke-width:0.0140468" + id="path1732" /> + <path + d="M 8.0669165,249.07843 H 7.7392283 v -1.36396 q 0,-0.15442 -0.012201,-0.2981 -0.010458,-0.14369 -0.047062,-0.22947 -0.040089,-0.0923 -0.1150395,-0.13941 -0.07495,-0.0472 -0.2161348,-0.0472 -0.1376987,0 -0.2753975,0.0858 -0.1376988,0.0837 -0.2753976,0.21446 0.00523,0.0493 0.00872,0.11578 0.00349,0.0644 0.00349,0.12868 v 1.53339 H 6.4825091 v -1.36397 q 0,-0.15869 -0.012201,-0.30024 -0.010458,-0.14369 -0.047062,-0.22948 -0.040089,-0.0923 -0.1150395,-0.13725 -0.07495,-0.0472 -0.2161348,-0.0472 -0.1342127,0 -0.2701685,0.0815 -0.1342127,0.0814 -0.2684254,0.20802 v 1.7886 h -0.327688 v -2.39552 h 0.3276882 v 0.26593 q 0.153386,-0.15656 0.3050289,-0.24448 0.153386,-0.088 0.3259452,-0.088 0.1987046,0 0.3364034,0.10298 0.1394418,0.10299 0.2074196,0.28523 0.1987046,-0.20588 0.3625487,-0.29596 0.1638441,-0.0923 0.3503475,-0.0923 0.3207162,0 0.4723591,0.2402 0.153386,0.23806 0.153386,0.66697 z" + style="stroke-width:0.0155811" + id="path1734" /> + <path + d="M 10.327617,247.92249 H 8.8931091 q 0,0.22089 0.054034,0.38603 0.054034,0.16299 0.1481569,0.26808 0.090637,0.10299 0.2143918,0.1544 0.1254976,0.0514 0.2753975,0.0514 0.1987046,0 0.3991522,-0.0965 0.2021905,-0.0987 0.2875985,-0.19301 h 0.01743 v 0.43964 q -0.165587,0.0858 -0.3381459,0.14369 -0.1725593,0.058 -0.3625487,0.058 -0.4845603,0 -0.7564718,-0.32169 -0.2719115,-0.32384 -0.2719115,-0.91789 0,-0.58761 0.2597104,-0.9329 0.2614533,-0.34528 0.6867508,-0.34528 0.3939231,0 0.6065717,0.28308 0.214392,0.28309 0.214392,0.80424 z m -0.318974,-0.30882 q -0.0017,-0.3174 -0.1307262,-0.49111 -0.1272406,-0.17372 -0.388694,-0.17372 -0.2631964,0 -0.4200684,0.19087 -0.155129,0.19087 -0.1760453,0.47396 z" + style="stroke-width:0.0155811" + id="path1736" /> + </g> + <g + aria-label="scan" + transform="scale(0.86291641,1.1588608)" + id="text1665" + style="font-style:normal;font-weight:normal;font-size:4.11687px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0161999" /> + </g> + </g> +</svg> diff --git a/res/blank-clock-mode-scan.svg b/res/blank-clock-mode-scan.svg @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="10mm" + height="5mm" + viewBox="0 0 10 5" + version="1.1" + id="svg890" + inkscape:version="1.0.1 (c497b03c, 2020-09-10)" + sodipodi:docname="blank-clock-mode-scan.svg"> + <defs + id="defs884" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="7.919596" + inkscape:cx="23.925645" + inkscape:cy="2.8363977" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + units="mm" + inkscape:window-width="1440" + inkscape:window-height="855" + inkscape:window-x="0" + inkscape:window-y="23" + inkscape:window-maximized="1" + inkscape:snap-global="false" + inkscape:document-rotation="0" /> + <metadata + id="metadata887"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-292)"> + <g + aria-label="rst" + style="font-style:normal;font-weight:normal;font-size:6.29599571px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15739989" + id="text1460"> + <rect + style="fill:#dedede;fill-opacity:1;stroke:#000000;stroke-width:0.0405524;stroke-opacity:1" + id="rect2390" + width="8.3529882" + height="3.7808547" + x="0.21206512" + y="292.08575" /> + <path + style="fill:#adadad;fill-opacity:1;stroke:#000000;stroke-width:0.127101;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.6030589,292.15394 1.0204635,0.59028 0.051021,4.14452 -1.071485,-1.00207 z" + id="path2394" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#848484;fill-opacity:1;stroke:#000000;stroke-width:0.152046;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0.30053403,295.89944 0.60512692,0.7811 8.68875495,0.15756 -1.1553752,-0.98493 z" + id="path2396" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <g + aria-label="scan" + transform="scale(0.86291641,1.1588608)" + id="text1665" + style="font-style:normal;font-weight:normal;font-size:4.11687px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0161999"> + <path + d="m 2.4628883,254.11409 q 0,0.30756 -0.2890876,0.54648 -0.2868111,0.23861 -0.7853164,0.31093 -0.2822587,0.041 -0.51899195,0.017 -0.23445681,-0.0263 -0.3937964,-0.0735 v -0.42415 l 0.0227628,-0.003 q 0.20258891,0.10529 0.45070344,0.14971 0.24811451,0.0424 0.47574251,0.009 0.2822587,-0.0409 0.4415982,-0.14446 0.1593397,-0.10352 0.1593397,-0.27641 0,-0.13267 -0.086498,-0.18847 -0.086498,-0.0558 -0.3323369,-0.0684 -0.091052,-0.005 -0.2390094,-0.008 -0.1456818,-0.003 -0.2663247,-0.0137 -0.33461319,-0.0299 -0.47574254,-0.16014 -0.13885308,-0.13263 -0.13885308,-0.35375 0,-0.13871 0.0637358,-0.27057 0.0660121,-0.1322 0.19803635,-0.24784 0.12747163,-0.113 0.32323187,-0.19565 0.1980364,-0.085 0.4415982,-0.12036 0.2276281,-0.033 0.4598086,-0.0164 0.2344568,0.0142 0.3892438,0.0622 v 0.40404 l -0.022763,0.003 q -0.1638923,-0.0828 -0.3983491,-0.12111 -0.2344568,-0.0404 -0.4598085,-0.008 -0.2344568,0.034 -0.3960727,0.13786 -0.16161588,0.10185 -0.16161588,0.25864 0,0.1387 0.0978798,0.19486 0.095604,0.0565 0.3095741,0.0697 0.1183666,0.007 0.2640485,0.01 0.1479582,0.003 0.2458382,0.009 0.2981927,0.017 0.4598085,0.14034 0.1616159,0.12531 0.1616159,0.37056 z" + style="stroke-width:0.0172388" + id="path1667" /> + <path + d="m 4.4546143,254.69481 q -0.1970533,0.0804 -0.3722477,0.12149 -0.1731967,0.0413 -0.36369,0.0313 -0.2426282,-0.0128 -0.4384897,-0.0936 -0.1956723,-0.0829 -0.3263512,-0.23481 -0.1326803,-0.15208 -0.1919604,-0.37687 -0.05928,-0.22479 -0.031313,-0.51956 0.052129,-0.54942 0.3825869,-0.8464 0.3324633,-0.29689 0.8277457,-0.27083 0.1924985,0.0101 0.3718371,0.074 0.1813437,0.064 0.3283263,0.15027 l -0.039763,0.41909 -0.020052,-0.001 q -0.1597,-0.14342 -0.3373283,-0.22531 -0.1756203,-0.0818 -0.350072,-0.091 -0.3208307,-0.0169 -0.5278607,0.18987 -0.2048347,0.20485 -0.244407,0.62193 -0.038431,0.40505 0.121299,0.63311 0.1619254,0.22616 0.4907769,0.24346 0.114296,0.006 0.2354511,-0.0178 0.1211645,-0.0239 0.2199704,-0.067 0.086207,-0.0378 0.1627663,-0.0801 0.076749,-0.0443 0.1220946,-0.0762 l 0.020052,0.001 z" + style="stroke-width:0.0161999" + id="path1669" /> + <path + d="M 7.1296643,253.99974 H 6.6850978 v -0.17498 q -0.059434,0.025 -0.1616604,0.0706 -0.099849,0.0441 -0.1949435,0.0706 -0.111736,0.0338 -0.256755,0.0559 -0.145019,0.0236 -0.3399625,0.0236 -0.3589813,0 -0.6086042,-0.14704 -0.2496228,-0.14703 -0.2496228,-0.37494 0,-0.18675 0.1283774,-0.30144 0.1307548,-0.11616 0.3708683,-0.18233 0.2424907,-0.0662 0.5824532,-0.0897 0.3399625,-0.0236 0.7298495,-0.0353 v -0.0427 q 0,-0.0941 -0.054679,-0.15586 -0.052302,-0.0617 -0.1521511,-0.097 -0.095095,-0.0338 -0.2282266,-0.0456 -0.1331322,-0.0118 -0.2781512,-0.0118 -0.1759247,0 -0.3922644,0.0294 -0.2163398,0.028 -0.4469437,0.0823 h -0.023774 v -0.28085 q 0.1307549,-0.0221 0.3780004,-0.0485 0.2472454,-0.0265 0.4873588,-0.0265 0.2805285,0 0.4873589,0.0294 0.2092076,0.0279 0.3613587,0.097 0.1497737,0.0677 0.2282266,0.17497 0.078453,0.10734 0.078453,0.26614 z m -0.4445665,-0.40436 v -0.4573 q -0.2044529,0.007 -0.4826041,0.0221 -0.2757738,0.0147 -0.4374342,0.0427 -0.1925663,0.0338 -0.3114343,0.10587 -0.118868,0.0706 -0.118868,0.19556 0,0.14116 0.1378869,0.21321 0.137887,0.0706 0.4207928,0.0706 0.2353587,0 0.4303022,-0.0559 0.1949435,-0.0573 0.3613587,-0.13674 z" + style="stroke-width:0.0150675" + id="path1671" /> + <path + d="m 9.390447,254.32893 -0.3779158,0.11606 v -1.27848 q 0,-0.15479 -0.018092,-0.28391 -0.018092,-0.13114 -0.066336,-0.19271 -0.050255,-0.069 -0.1447337,-0.0802 -0.094479,-0.0132 -0.2452432,0.0331 -0.1547847,0.0476 -0.3236407,0.17584 -0.168856,0.12845 -0.3236406,0.29433 v 1.6765 l -0.3779158,0.11606 v -2.24538 L 7.890845,252.5441 v 0.24926 q 0.1768967,-0.20108 0.3658546,-0.34155 0.1889579,-0.14027 0.3879668,-0.20154 0.3638444,-0.11174 0.5548125,0.0487 0.1909681,0.16046 0.1909681,0.57255 z" + style="stroke-width:0.0161999" + id="path1673" /> + </g> + </g> + </g> +</svg> diff --git a/res/blank-clock-mode-sync.svg b/res/blank-clock-mode-sync.svg @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="10mm" + height="5mm" + viewBox="0 0 10 5" + version="1.1" + id="svg890" + inkscape:version="1.0.1 (c497b03c, 2020-09-10)" + sodipodi:docname="blank-clock-mode-sync.svg"> + <defs + id="defs884" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="7.919596" + inkscape:cx="23.420569" + inkscape:cy="5.7405863" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + units="mm" + inkscape:window-width="1440" + inkscape:window-height="855" + inkscape:window-x="0" + inkscape:window-y="23" + inkscape:window-maximized="1" + inkscape:snap-global="false" + inkscape:document-rotation="0" /> + <metadata + id="metadata887"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-292)"> + <g + aria-label="rst" + style="font-style:normal;font-weight:normal;font-size:6.29599571px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15739989" + id="text1460"> + <rect + style="fill:#dedede;fill-opacity:1;stroke:#000000;stroke-width:0.0405524;stroke-opacity:1" + id="rect2390" + width="8.3529882" + height="3.7808547" + x="0.21206512" + y="292.08575" /> + <path + style="fill:#adadad;fill-opacity:1;stroke:#000000;stroke-width:0.125246;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 8.6020613,292.1531 0.9905456,0.59048 0.049525,4.14601 -1.0400712,-1.00243 z" + id="path2394" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:#848484;fill-opacity:1;stroke:#000000;stroke-width:0.152297;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 0.30065978,295.89955 0.6072858,0.78091 8.71975332,0.15752 -1.1594972,-0.98469 z" + id="path2396" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + <g + aria-label="sync" + transform="scale(0.86381097,1.1576607)" + id="text1625" + style="font-style:normal;font-weight:normal;font-size:3.56971px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.0140468"> + <path + d="m 2.6407958,254.40975 q 0,0.336 -0.2804824,0.55123 -0.2782737,0.21521 -0.7619401,0.21521 -0.2738567,0 -0.5035429,-0.0636 -0.22747787,-0.0659 -0.38207442,-0.14275 v -0.46338 h 0.0220852 q 0.19655845,0.14713 0.43728742,0.23498 0.2407288,0.0857 0.4615811,0.0857 0.2738566,0 0.4284532,-0.0878 0.1545965,-0.0878 0.1545965,-0.27671 0,-0.14494 -0.083924,-0.21961 -0.083924,-0.0747 -0.3224441,-0.12738 -0.088341,-0.0198 -0.2318949,-0.0461 -0.1413453,-0.0263 -0.2583971,-0.0571 -0.3246527,-0.0857 -0.46158106,-0.25035 -0.13471985,-0.16691 -0.13471985,-0.40849 0,-0.15152 0.0618387,-0.2855 0.0640472,-0.13395 0.19214141,-0.23938 0.1236772,-0.10319 0.3136102,-0.1625 0.1921414,-0.0615 0.4284532,-0.0615 0.2208522,0 0.4461214,0.0549 0.2274778,0.0527 0.3776573,0.12958 v 0.44142 h -0.022085 q -0.1590135,-0.11642 -0.3864913,-0.19545 -0.2274778,-0.0813 -0.4461215,-0.0813 -0.2274778,0 -0.3842829,0.0878 -0.1568051,0.0857 -0.1568051,0.25694 0,0.15154 0.094966,0.22839 0.092758,0.0769 0.3003589,0.12524 0.1148429,0.0263 0.2561885,0.0527 0.143554,0.0263 0.2385205,0.0483 0.2893164,0.0659 0.4461213,0.22621 0.1568051,0.16251 0.1568051,0.43044 z" + style="stroke-width:0.0177482" + id="path1636" /> + <path + d="m 4.9171482,252.89649 -1.2997931,2.37213 -0.4007031,-0.0903 0.4146579,-0.71879 -0.8871288,-2.05277 0.4066838,0.0917 0.6837869,1.59734 0.6897675,-1.28776 z" + style="stroke-width:0.0150224" + id="path1638" /> + <path + d="M 7.2695347,255.04751 H 6.8191966 v -1.10856 q 0,-0.13421 -0.021558,-0.251 -0.021558,-0.11852 -0.079049,-0.18476 -0.059886,-0.0732 -0.17247,-0.10806 -0.1125842,-0.0366 -0.2922408,-0.0366 -0.184447,0 -0.385662,0.0662 -0.201215,0.0662 -0.385662,0.16907 v 1.45368 H 5.0322162 v -1.94695 h 0.4503382 v 0.21613 q 0.2107966,-0.12724 0.4359657,-0.1987 0.2251692,-0.0715 0.4623153,-0.0715 0.4335703,0 0.6611348,0.18999 0.2275645,0.18999 0.2275645,0.54731 z" + style="stroke-width:0.0164671" + id="path1640" /> + <path + d="m 9.6378696,254.88898 q -0.1873935,0.0957 -0.3568451,0.14891 -0.1674579,0.0532 -0.3568451,0.0532 -0.2412192,0 -0.4425676,-0.0744 -0.2013482,-0.0765 -0.3448838,-0.22975 -0.1455289,-0.15318 -0.2252708,-0.38719 -0.079742,-0.23402 -0.079742,-0.54674 0,-0.58291 0.2990322,-0.91478 0.3010258,-0.33187 0.793432,-0.33187 0.1913807,0 0.374787,0.0575 0.1853999,0.0575 0.3389032,0.1404 v 0.44463 h -0.019935 q -0.1714451,-0.14254 -0.3548515,-0.21912 -0.1814128,-0.0765 -0.3548515,-0.0765 -0.3189677,0 -0.5043675,0.22976 -0.1834065,0.22763 -0.1834065,0.67013 0,0.42973 0.1794193,0.66162 0.1814129,0.22975 0.5083547,0.22975 0.1136319,0 0.2312515,-0.0319 0.1176194,-0.032 0.2113161,-0.083 0.081736,-0.0447 0.1535032,-0.0936 0.071768,-0.051 0.1136319,-0.0873 h 0.019935 z" + style="stroke-width:0.0165963" + id="path1642" /> + </g> + </g> + </g> +</svg> diff --git a/src/ComputerscareBlank.cpp b/src/ComputerscareBlank.cpp @@ -13,6 +13,7 @@ struct ComputerscareBlank; struct ComputerscareBlank : ComputerscareMenuParamModule { bool loading = true; bool loadedJSON = false; + bool ready = false; std::string path; std::string parentDirectory; @@ -29,17 +30,37 @@ struct ComputerscareBlank : ComputerscareMenuParamModule { int imageFitEnum = 0; int currentFrame = 0; int numFrames = 0; - int stepCounter = 0; + int sampleCounter = 0; float frameDelay = .5; std::vector<float> frameDelays; + float totalGifDuration = 0.f; int samplesDelay = 10000; int speed = 100000; int imageStatus = 0; + bool expanderConnected = false; + + int clockMode = 0; + bool clockConnected = false; + bool resetConnected = false; + bool speedConnected = false; + + float leftMessages[2][8] = {}; + + int pingPongDirection = 1; + + float speedFactor = 1.f; + std::vector<std::string> animationModeDescriptions; std::vector<std::string> endBehaviorDescriptions; + dsp::SchmittTrigger clockTrigger; + dsp::SchmittTrigger resetTrigger; + + dsp::Timer syncTimer; + + ComputerscareSVGPanel* panelRef; enum ParamIds { ANIMATION_SPEED, @@ -79,43 +100,82 @@ struct ComputerscareBlank : ComputerscareMenuParamModule { endBehaviorDescriptions.push_back("Load Next"); endBehaviorDescriptions.push_back("Load Previous"); - configMenuParam(ANIMATION_MODE, 0.f, "Animation Mode", animationModeDescriptions); - paths.push_back("empty"); + + leftExpander.producerMessage = leftMessages[0]; + leftExpander.consumerMessage = leftMessages[1]; } void process(const ProcessArgs &args) override { - stepCounter++; + sampleCounter++; samplesDelay = frameDelay * args.sampleRate; - if (stepCounter > samplesDelay) { - stepCounter = 0; - if (params[ANIMATION_ENABLED].getValue()) { + bool shouldAdvanceAnimation = false; + if (leftExpander.module && leftExpander.module->model == modelComputerscareBlankExpander) { + expanderConnected = true; + // me + float *messageToSendToExpander = (float*) leftExpander.module->rightExpander.producerMessage; + + float *messageFromExpander = (float*) leftExpander.consumerMessage; + + clockMode = messageFromExpander[0]; + clockConnected = messageFromExpander[1]; + resetConnected = messageFromExpander[3]; + speedConnected = messageFromExpander[5]; + + if (clockConnected) { + bool clockTriggered = clockTrigger.process(messageFromExpander[2]); + if (clockMode == 0) { + //sync + float currentSyncTime = syncTimer.process(args.sampleTime); + if (clockTriggered) { + syncTimer.reset(); + setSyncTime(currentSyncTime); + goToFrame(0); + } + } - if (numFrames > 1) { - tickAnimation(); + else if (clockMode == 1) { + //scan + float scanPosition = messageFromExpander[2]; + } + else if (clockMode == 2) { + //frame advance + shouldAdvanceAnimation = clockTriggered; } } - } - if (rightExpander.module && rightExpander.module->model == modelComputerscareBlankExpander) { - // Get message from right expander - float *message = (float*) rightExpander.module->leftExpander.producerMessage; - // Write message - /*for (int i = 0; i < 8; i++) { - message[i] = inputs[i].getVoltage() / 10.f; - }*/ - if (stepCounter == 90) { - + if (resetConnected) { + if (resetTrigger.process(messageFromExpander[4])) { + DEBUG("RESSSSSTT"); + } } - message[0] = (currentFrame == 0) ? 10.f : 0.f; + + messageToSendToExpander[0] = float (currentFrame); // Flip messages at the end of the timestep - rightExpander.module->leftExpander.messageFlipRequested = true; + leftExpander.module->rightExpander.messageFlipRequested = true; + } + else { + expanderConnected = false; + } + + if (clockConnected && (clockMode == 2)) { + } else { + if (sampleCounter > samplesDelay) { + sampleCounter = 0; + shouldAdvanceAnimation = true; + } + } + if (params[ANIMATION_ENABLED].getValue() && shouldAdvanceAnimation) { + tickAnimation(); } } + + + void onReset() override { zoomX = 1; zoomY = 1; @@ -184,57 +244,106 @@ struct ComputerscareBlank : ComputerscareMenuParamModule { void setImageStatus(int status) { imageStatus = status; } + void setSyncTime(float syncDuration) { + speedFactor = totalGifDuration / syncDuration; + } void setFrameDelay(float frameDelaySeconds) { float speedKnob = abs(params[ANIMATION_SPEED].getValue()); + float appliedSpeedDivisor = 1; float base = frameDelaySeconds; - if (speedKnob == 0) { - frameDelay = 10000000; + + if (expanderConnected && clockConnected && (clockMode == 0)) { + appliedSpeedDivisor = speedFactor; } else { - if (params[CONSTANT_FRAME_DELAY].getValue()) { - frameDelay = .04 / speedKnob; - } - else { - frameDelay = base / speedKnob; - } + appliedSpeedDivisor = speedKnob; + } + + + if (params[CONSTANT_FRAME_DELAY].getValue()) { + frameDelay = .04 / appliedSpeedDivisor; + } + else { + frameDelay = base / appliedSpeedDivisor; } + } void setFrameDelays(std::vector<float> frameDelaysSeconds) { frameDelays = frameDelaysSeconds; + ready = true; + } + void setTotalGifDuration(float totalDuration) { + totalGifDuration = totalDuration; } std::string getPath() { //return numFrames > 0 ? paths[currentFrame] : ""; return paths[0]; } void tickAnimation() { - if (params[ANIMATION_SPEED].getValue() >= 0 ) { - nextFrame(); - } - else { - prevFrame(); - } - if (currentFrame == 0) { - int eb = params[END_BEHAVIOR].getValue(); - if (eb == 3 ) { - loadRandomGif(); + if (numFrames > 1) { + int animationMode = params[ANIMATION_MODE].getValue(); + if (params[ANIMATION_SPEED].getValue() >= 0 ) { + if (animationMode == 0) { + nextFrame(); + } else if (animationMode == 1) { + prevFrame(); + } + else if (animationMode == 2) { + pingPongDirection == 1 ? nextFrame() : prevFrame(); + } + else if (animationMode == 4 ) { + goToRandomFrame(); + } + + } + else { + prevFrame(); + } + if (currentFrame == numFrames - 1) { + if (animationMode == 2 ) { + pingPongDirection = -1; + } } + if (currentFrame == 0) { + int eb = params[END_BEHAVIOR].getValue(); + + if (animationMode == 2) { + pingPongDirection = 1; + } + if (eb == 3 ) { + loadRandomGif(); + } + } + //setFrameDelay(frameDelays[currentFrame]); + } + DEBUG("current:%i, samplesDelay:%i", currentFrame, samplesDelay); + } + void setCurrentFrameDelayFromTable() { + if (ready) { + setFrameDelay(frameDelays[currentFrame]); } - setFrameDelay(frameDelays[currentFrame]); } void nextFrame() { currentFrame++; currentFrame %= numFrames; + setCurrentFrameDelayFromTable(); } void prevFrame() { currentFrame--; currentFrame += numFrames; currentFrame %= numFrames; + setCurrentFrameDelayFromTable(); } void goToFrame(int frameNum) { - currentFrame = 0; + sampleCounter = 0; + currentFrame = frameNum; + currentFrame += numFrames; + currentFrame %= numFrames; + setCurrentFrameDelayFromTable(); } void goToRandomFrame() { currentFrame = (int) std::floor(random::uniform() * numFrames); + setCurrentFrameDelayFromTable(); } void toggleAnimationEnabled() { float current = params[ANIMATION_ENABLED].getValue(); @@ -413,6 +522,7 @@ struct PNGDisplay : TransparentWidget { blankModule->setFrameCount(gifBuddy.getFrameCount()); blankModule->setFrameDelays(gifBuddy.getAllFrameDelaysSeconds()); + blankModule->setTotalGifDuration(gifBuddy.getTotalGifDuration()); blankModule->setFrameDelay(gifBuddy.getSecondsDelay(0)); blankModule->setImageStatus(gifBuddy.getImageStatus()); @@ -444,7 +554,7 @@ struct PNGDisplay : TransparentWidget { nvgClosePath(args.vg); } //if (blankModule->currentFrame != currentFrame) { - gifBuddy.displayGifFrame(args.vg, currentFrame); + gifBuddy.displayGifFrame(args.vg, currentFrame); //} } } @@ -453,7 +563,7 @@ struct PNGDisplay : TransparentWidget { if (blankModule->currentFrame != currentFrame) { currentFrame = blankModule->currentFrame; //blankModule->setFrameDelay(gifBuddy.getSecondsDelay(currentFrame)); - + } } TransparentWidget::step(); diff --git a/src/ComputerscareBlankExpander.cpp b/src/ComputerscareBlankExpander.cpp @@ -1,19 +1,24 @@ #include "Computerscare.hpp" struct ComputerscareBlankExpander : Module { - float leftMessages[2][1] = {}; + float rightMessages[2][8] = {}; bool isConnected = false; + float lastFrame = -1; + enum ParamIds { + CLOCK_MODE, + MANUAL_RESET_BUTTON, NUM_PARAMS }; enum InputIds { - CLOCK_INPUT, + SYNC_INPUT, RESET_INPUT, - SCAN_INPUT, + SPEED_INPUT, NUM_INPUTS }; enum OutputIds { EOC_OUTPUT, + EACH_FRAME_OUTPUT, NUM_OUTPUTS }; enum LightIds { @@ -21,38 +26,83 @@ struct ComputerscareBlankExpander : Module { }; dsp::SchmittTrigger eocMessageReadTrigger; + dsp::SchmittTrigger eachFrameReadTrigger; + + dsp::SchmittTrigger syncTrigger; + dsp::PulseGenerator eocPulse; dsp::PulseGenerator eachFramePulse; + dsp::Timer syncTimer; + + std::vector<std::string> clockModeDescriptions; + ComputerscareBlankExpander() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + configParam(CLOCK_MODE, 0.f, 2.f, 0.f, "Clock Mode"); + configParam(MANUAL_RESET_BUTTON, 0.f, 1.f, 0.f, "Manual Reset"); + + clockModeDescriptions.push_back("Sync"); + clockModeDescriptions.push_back("Scan"); + clockModeDescriptions.push_back("Frame Advance"); - leftExpander.producerMessage = leftMessages[0]; - leftExpander.consumerMessage = leftMessages[1]; + rightExpander.producerMessage = rightMessages[0]; + rightExpander.consumerMessage = rightMessages[1]; } void process(const ProcessArgs &args) override { - if (leftExpander.module && leftExpander.module->model == modelComputerscareBlank) { + if (rightExpander.module && rightExpander.module->model == modelComputerscareBlank) { // Get consumer message - float *message = (float*) leftExpander.consumerMessage; + float *messageFromMother = (float*) rightExpander.consumerMessage; isConnected = true; - //eocMessageReadTrigger.process(message[0]); - if (eocMessageReadTrigger.process(message[0])) { + float *messageToSendToMother = (float*) rightExpander.module->leftExpander.producerMessage; + + + float currentFrame = messageFromMother[0]; + float currentSyncTime = syncTimer.process(args.sampleTime); + + if (eocMessageReadTrigger.process(currentFrame == 0 ? 10.f : 0.f)) { eocPulse.trigger(1e-3); } + if (eachFrameReadTrigger.process(abs(currentFrame - lastFrame) * 10)) { + eachFramePulse.trigger(1e-3); + } + + + messageToSendToMother[0] = params[CLOCK_MODE].getValue(); + + messageToSendToMother[1] = inputs[SYNC_INPUT].isConnected(); + messageToSendToMother[2] = inputs[SYNC_INPUT].getVoltage(); + + messageToSendToMother[3] = inputs[RESET_INPUT].isConnected(); + messageToSendToMother[4] = inputs[RESET_INPUT].getVoltage(); + + messageToSendToMother[5] = inputs[SPEED_INPUT].isConnected(); + messageToSendToMother[6] = inputs[SPEED_INPUT].getVoltage(); + outputs[EOC_OUTPUT].setVoltage(eocPulse.process(args.sampleTime) ? 10.f : 0.f); + outputs[EACH_FRAME_OUTPUT].setVoltage(eachFramePulse.process(args.sampleTime) ? 10.f : 0.f); - leftExpander.module->rightExpander.messageFlipRequested = true; + rightExpander.module->leftExpander.messageFlipRequested = true; + lastFrame = currentFrame; } else { - // isConnected = false; + isConnected = false; // No mother module is connected. } } }; +struct ClockModeButton : app::SvgSwitch { + ClockModeButton() { + //momentary = true; + addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/blank-clock-mode-sync.svg"))); + addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/blank-clock-mode-scan.svg"))); + addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/blank-clock-mode-frame.svg"))); + } +}; struct ComputerscareBlankExpanderWidget : ModuleWidget { ComputerscareBlankExpanderWidget(ComputerscareBlankExpander *module) { setModule(module); @@ -64,20 +114,26 @@ struct ComputerscareBlankExpanderWidget : ModuleWidget { addChild(panel); } - DEBUG("clock_input:%i", ComputerscareBlankExpander::CLOCK_INPUT); - float inStartY = 30; float dY = 40; float outStartY = 250; - addInput(createInput<InPort>(Vec(2, inStartY), module, ComputerscareBlankExpander::CLOCK_INPUT)); - addInput(createInput<InPort>(Vec(2, inStartY + dY), module, ComputerscareBlankExpander::SCAN_INPUT)); - addInput(createInput<InPort>(Vec(2, inStartY + 2 * dY), module, ComputerscareBlankExpander::RESET_INPUT)); + addParam(createParam<ClockModeButton>(Vec(0.5, inStartY+dY/2), module, ComputerscareBlankExpander::CLOCK_MODE)); - addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY), module, ComputerscareBlankExpander::EOC_OUTPUT)); + addInput(createInput<InPort>(Vec(2, inStartY+dY), module, ComputerscareBlankExpander::SYNC_INPUT)); + + addParam(createParam<ComputerscareResetButton>(Vec(0, inStartY+2*dY), module, ComputerscareBlankExpander::MANUAL_RESET_BUTTON)); + + addInput(createInput<InPort>(Vec(2, inStartY + 3*dY), module, ComputerscareBlankExpander::RESET_INPUT)); + addInput(createInput<InPort>(Vec(2, inStartY + 4 * dY), module, ComputerscareBlankExpander::SPEED_INPUT)); + addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY + dY), module, ComputerscareBlankExpander::EACH_FRAME_OUTPUT)); + addOutput(createOutput<PointingUpPentagonPort>(Vec(2, outStartY), module, ComputerscareBlankExpander::EOC_OUTPUT)); + } + void step() { + ModuleWidget::step(); } }; Model *modelComputerscareBlankExpander = createModel<ComputerscareBlankExpander, ComputerscareBlankExpanderWidget>("computerscare-blank-expander"); diff --git a/src/animatedGif.hpp b/src/animatedGif.hpp @@ -147,6 +147,8 @@ struct AnimatedGifBuddy { std::vector<unsigned char*> framePointers; std::vector<int> frameDelays; std::vector<float> frameDelaysSeconds; + float totalGifDuration; + int imageHandle; bool initialized = false; int numFrames = -1; @@ -211,11 +213,18 @@ struct AnimatedGifBuddy { } void updateFrameDelaysSeconds() { frameDelaysSeconds.resize(0); + totalGifDuration = 0.f; + float thisDurationSeconds; for (unsigned int i = 0; i < frameDelays.size(); i++) { - frameDelaysSeconds.push_back( ((float) frameDelays[i]) / 100); + thisDurationSeconds = ((float) frameDelays[i]) / 100; + totalGifDuration += thisDurationSeconds; + frameDelaysSeconds.push_back(thisDurationSeconds ); } } std::vector<float> getAllFrameDelaysSeconds() { return frameDelaysSeconds; } + float getTotalGifDuration() { + return totalGifDuration; + } }; \ No newline at end of file