Phase 8 — Companion webapp bridge: - NISPS-FORMAT.md: full .nisps JSON schema with validation rules - Webapp iml.js: exportState() / importState() with bias handling - osc_server.hpp: minimal UDP OSC server (cross-platform, no deps) - VCV module: OSC toggle + port selection in right-click menu - osc-client.js: WebSocket client with auto-reconnect - Bridge scripts updated for bidirectional VCV↔webapp relay Phase 9 — Panel layout variants: - MEMLNaut.svg: 30HP standard panel (matches widget positions) - MEMLNaut-wide.svg: 44HP with expanded display and 8 input slots - MEMLNaut-expander.svg: 8HP with 6 extra inputs and LINK LED Phase 10 — Polish & distribution: - README.md: 267-line user guide (install, quick start, RL workflow, presets, OSC, technical details) - BUILDING.md: build prerequisites, SDK setup, local install - Makefile.dist: platform-stamped zip packaging - SPEC.md: performance characteristics (1060 MADs/pass, ~46KB/instance) - SPEC.md: v1 compatibility assessment (v2-only recommended)
217 lines
14 KiB
XML
217 lines
14 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" width="223.52mm" height="128.5mm" viewBox="0 0 223.52 128.5">
|
|
<defs>
|
|
<style>
|
|
text { font-family: 'Courier New', monospace; }
|
|
.title { font-size: 6; fill: #e0e0e0; }
|
|
.subtitle { font-size: 3; fill: #4a9eff; }
|
|
.section-label { font-size: 3; fill: #808080; }
|
|
.component-label { font-size: 2.5; fill: #808080; }
|
|
.output-num { font-size: 2.5; fill: #4a9eff; }
|
|
.footer { font-size: 2.5; fill: #808080; }
|
|
</style>
|
|
</defs>
|
|
|
|
<!-- Background -->
|
|
<rect width="223.52" height="128.5" fill="#1a1a2e"/>
|
|
|
|
<!-- Panel border -->
|
|
<rect x="0.5" y="0.5" width="222.52" height="127.5" fill="none" stroke="#2a2a3e" stroke-width="0.5"/>
|
|
|
|
<!-- Title -->
|
|
<text x="111.76" y="8" text-anchor="middle" class="title">MEMLNaut</text>
|
|
<text x="111.76" y="12" text-anchor="middle" class="subtitle">Neural Interactive Shaping of Parameter Spaces</text>
|
|
<line x1="20" y1="13.5" x2="203" y2="13.5" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- DISPLAY AREA: wider — (2, 16) to (60, 34) -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<rect x="2" y="16" width="56" height="18" rx="1" fill="#0a0a18" stroke="#2a2a3e" stroke-width="0.4"/>
|
|
<text x="30" y="26" text-anchor="middle" class="component-label" fill="#4a9eff">DISPLAY</text>
|
|
<text x="30" y="30" text-anchor="middle" class="component-label" fill="#333355">input space / output map</text>
|
|
|
|
<line x1="0" y1="36" x2="223.52" y2="36" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- KNOBS ROW: y=40 -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<text x="14" y="38" text-anchor="middle" class="section-label">SPREAD</text>
|
|
<circle cx="14" cy="41" r="4" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
<circle cx="14" cy="41" r="0.7" fill="#4a9eff"/>
|
|
|
|
<text x="28" y="38" text-anchor="middle" class="component-label">CV</text>
|
|
<circle cx="28" cy="41" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="42" y="38" text-anchor="middle" class="section-label">RATE</text>
|
|
<circle cx="42" cy="41" r="4" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
<circle cx="42" cy="41" r="0.7" fill="#4a9eff"/>
|
|
|
|
<line x1="0" y1="48" x2="223.52" y2="48" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- BUTTONS ROW: y=53 -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<text x="10" y="50.5" text-anchor="middle" class="section-label" fill="#4a9eff">+</text>
|
|
<rect x="7" y="51" width="6" height="4.5" rx="0.8" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="20" y="50.5" text-anchor="middle" class="section-label" fill="#4a9eff">−</text>
|
|
<rect x="17" y="51" width="6" height="4.5" rx="0.8" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="32" y="50.5" text-anchor="middle" class="section-label">LEARN</text>
|
|
<rect x="30" y="51" width="4" height="5.5" rx="0.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
<circle cx="32" cy="49" r="0.8" fill="none" stroke="#00cc00" stroke-width="0.3"/>
|
|
|
|
<text x="44" y="50.5" text-anchor="middle" class="section-label">RAND</text>
|
|
<rect x="41" y="51" width="6" height="4.5" rx="0.8" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="56" y="50.5" text-anchor="middle" class="section-label">CLR</text>
|
|
<rect x="53" y="51" width="6" height="4.5" rx="0.8" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
<circle cx="56" cy="49" r="0.8" fill="none" stroke="#cccc00" stroke-width="0.3"/>
|
|
|
|
<line x1="0" y1="59" x2="223.52" y2="59" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- INPUTS: 8 jacks (future configurable) -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<text x="50" y="61.5" text-anchor="middle" class="section-label" fill="#e0e0e0">IN</text>
|
|
|
|
<!-- Row 1: X, Y, IN3-IN6 -->
|
|
<text x="10" y="63.5" text-anchor="middle" class="component-label">X</text>
|
|
<circle cx="10" cy="66" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="22" y="63.5" text-anchor="middle" class="component-label">Y</text>
|
|
<circle cx="22" cy="66" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="34" y="63.5" text-anchor="middle" class="component-label">IN 3</text>
|
|
<circle cx="34" cy="66" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<text x="46" y="63.5" text-anchor="middle" class="component-label">IN 4</text>
|
|
<circle cx="46" cy="66" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<text x="58" y="63.5" text-anchor="middle" class="component-label">IN 5</text>
|
|
<circle cx="58" cy="66" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<text x="70" y="63.5" text-anchor="middle" class="component-label">IN 6</text>
|
|
<circle cx="70" cy="66" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<!-- Row 2: IN7, IN8, LEARN gate, +TRIG, -TRIG -->
|
|
<text x="10" y="72" text-anchor="middle" class="component-label">IN 7</text>
|
|
<circle cx="10" cy="74.5" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<text x="22" y="72" text-anchor="middle" class="component-label">IN 8</text>
|
|
<circle cx="22" cy="74.5" r="2.5" fill="none" stroke="#555555" stroke-width="0.4" stroke-dasharray="1,0.5"/>
|
|
|
|
<text x="46" y="72" text-anchor="middle" class="component-label">LEARN</text>
|
|
<circle cx="46" cy="74.5" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="58" y="72" text-anchor="middle" class="component-label">+TRIG</text>
|
|
<circle cx="58" cy="74.5" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<text x="70" y="72" text-anchor="middle" class="component-label">−TRIG</text>
|
|
<circle cx="70" cy="74.5" r="2.5" fill="none" stroke="#808080" stroke-width="0.4"/>
|
|
|
|
<!-- Vertical divider between inputs and outputs -->
|
|
<line x1="85" y1="59" x2="85" y2="118" stroke="#2a2a3e" stroke-width="0.4"/>
|
|
|
|
<line x1="0" y1="80" x2="85" y2="80" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- OUTPUTS: right side, 4 cols x 3 rows for generous spacing -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<text x="154" y="61.5" text-anchor="middle" class="section-label" fill="#e0e0e0">OUT</text>
|
|
|
|
<!-- Output grid: 4 columns x 3 rows, generous spacing -->
|
|
<!-- Col centers: 100, 120, 140, 160 Row centers: 68, 80, 92 -->
|
|
|
|
<!-- Row 0: 1-4 -->
|
|
<text x="100" y="65" text-anchor="middle" class="output-num">1</text>
|
|
<circle cx="96" cy="68" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="100.5" cy="68" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="105" cy="68" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="120" y="65" text-anchor="middle" class="output-num">2</text>
|
|
<circle cx="116" cy="68" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="120.5" cy="68" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="125" cy="68" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="140" y="65" text-anchor="middle" class="output-num">3</text>
|
|
<circle cx="136" cy="68" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="140.5" cy="68" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="145" cy="68" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="160" y="65" text-anchor="middle" class="output-num">4</text>
|
|
<circle cx="156" cy="68" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="160.5" cy="68" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="165" cy="68" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<!-- Row 1: 5-8 -->
|
|
<text x="100" y="77" text-anchor="middle" class="output-num">5</text>
|
|
<circle cx="96" cy="80" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="100.5" cy="80" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="105" cy="80" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="120" y="77" text-anchor="middle" class="output-num">6</text>
|
|
<circle cx="116" cy="80" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="120.5" cy="80" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="125" cy="80" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="140" y="77" text-anchor="middle" class="output-num">7</text>
|
|
<circle cx="136" cy="80" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="140.5" cy="80" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="145" cy="80" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="160" y="77" text-anchor="middle" class="output-num">8</text>
|
|
<circle cx="156" cy="80" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="160.5" cy="80" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="165" cy="80" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<!-- Row 2: 9-12 -->
|
|
<text x="100" y="89" text-anchor="middle" class="output-num">9</text>
|
|
<circle cx="96" cy="92" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="100.5" cy="92" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="105" cy="92" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="120" y="89" text-anchor="middle" class="output-num">10</text>
|
|
<circle cx="116" cy="92" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="120.5" cy="92" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="125" cy="92" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="140" y="89" text-anchor="middle" class="output-num">11</text>
|
|
<circle cx="136" cy="92" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="140.5" cy="92" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="145" cy="92" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="160" y="89" text-anchor="middle" class="output-num">12</text>
|
|
<circle cx="156" cy="92" r="1.8" fill="none" stroke="#808080" stroke-width="0.3"/>
|
|
<circle cx="160.5" cy="92" r="0.6" fill="none" stroke="#ffffff" stroke-width="0.2"/>
|
|
<circle cx="165" cy="92" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<line x1="85" y1="99" x2="223.52" y2="99" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<!-- DERIVED OUTPUTS: wide spacing -->
|
|
<!-- ══════════════════════════════════════════════════════════════════ -->
|
|
<text x="100" y="103" text-anchor="middle" class="component-label">MN</text>
|
|
<circle cx="100" cy="106" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="117" y="103" text-anchor="middle" class="component-label">SD</text>
|
|
<circle cx="117" cy="106" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="134" y="103" text-anchor="middle" class="component-label">ΔT</text>
|
|
<circle cx="134" cy="106" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="151" y="103" text-anchor="middle" class="component-label">NV</text>
|
|
<circle cx="151" cy="106" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<text x="168" y="103" text-anchor="middle" class="component-label">CF</text>
|
|
<circle cx="168" cy="106" r="2.5" fill="none" stroke="#4a9eff" stroke-width="0.4"/>
|
|
|
|
<!-- Footer -->
|
|
<line x1="20" y1="122" x2="203" y2="122" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
<text x="111.76" y="126" text-anchor="middle" class="footer">NISPS v0.1</text>
|
|
|
|
<!-- Mounting holes -->
|
|
<circle cx="5.08" cy="3" r="1.2" fill="none" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
<circle cx="218.44" cy="3" r="1.2" fill="none" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
<circle cx="5.08" cy="125.5" r="1.2" fill="none" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
<circle cx="218.44" cy="125.5" r="1.2" fill="none" stroke="#2a2a3e" stroke-width="0.3"/>
|
|
</svg>
|