Commit graph

21 commits

Author SHA1 Message Date
monkey-w1n5t0n
3952c65d75 feat(firmware): on-device Joystick Dual/Single settings menu
Add glue/settings_view.hpp: wire_settings(mode) registers a "Joystick"
SingleSelectView on the MEMLNaut display carousel (TFT + rotary encoder, same
DisplayDriver as SystemView/SelfTest). For the 4-input two-joystick modes,
"Single" pins ML input channels 2,3 (the second joystick) to neutral via
ModeBase::set_input_pinned — the network is never rebuilt and trained state
survives toggling. Default is Dual. Only registered when input arity == 4.

Called from MEMLNaut-NISPS.ino setup() after addSystemInfoView(). MAP.md +
CLAUDE.md glue listings updated.

NOTE: compile-unverified — no arduino-cli/RP2350 toolchain on this host and no
hardware; needs scripts/build-firmware.sh + a flash test (chokepoint A).
2026-06-28 21:17:51 +02:00
monkey-w1n5t0n
9ddf7f0bd5 chore(docs): remove retired bd/beads block from CLAUDE.md — task tracking is ergo now (bd retired 2026-06-15) 2026-06-25 05:04:39 +02:00
w1n5t0n
3a8e2b8116 Stream 12: cleanup + docs (delete nisps-core, rewrite MAP/CLAUDE, create ALIGNMENT)
- Delete nisps-core/ (lessons absorbed into nisps/ml; firmware is canonical)
- Rewrite MAP.md to reflect new clean-slate layout (nisps/ + firmware/ + playground/ + schemas/ + codegen/)
- Rewrite CLAUDE.md as new architecture narrative
- Create ALIGNMENT.md with current strategic gaps + open mission questions

(meml-quc)
2026-04-29 19:57:27 +03:00
w1n5t0n
5fc37f760e Stream 6: extract firmware glue under firmware/
Move the Arduino sketch into firmware/MEMLNaut-NISPS/ and bridge the
hardware (memllib) to the platform-agnostic nisps/ library through a
slim glue layer. Delete the legacy root-level *AudioApp.hpp,
modes/MEMLNautMode*.hpp, voicespaces/, IMLInterface.hpp, XiasriAnalysis,
and the src/memlp submodule.

Glue layout (firmware/MEMLNaut-NISPS/glue/):
  audio_driver.hpp - bridge memllib block callback to Mode::process
                     via per-Mode templated trampoline (no virtual dispatch)
  peripherals.hpp  - joystick/pots/buttons -> Mode::set_input + ML primitives
  midi_io.hpp      - MIDI in -> mode.note_on/update_bpm/set_playing,
                     drains mode ControlEvent ring -> MIDI UART
  mode_select.hpp  - using-aliases mapping MEMLNautMode<Name> to
                     nisps::modes::*Mode (build script rewrites the
                     #define MEMLNAUT_MODE_TYPE line)
  input_router.hpp / output_router.hpp - top-level wire/drain entry points

The sketch tree uses src/{memllib,daisysp,nisps} symlinks because
Arduino-CLI rejects ".." in include paths from sketch-tree headers.
mode_select.hpp #undefs Arduino's sq/min/max/abs/round macros before
including nisps headers (some nisps engines use those identifiers as
method names). The audio bridge struct is extern in the header and
defined in the .ino because inline + __not_in_flash section attribute
collide at link time.

Verification: arduino-cli compile succeeds for PAFSynth, ChannelStrip,
and BreakOr (rp2040:rp2040:solderparty_rp2350_stamp_xl:opt=Optimize3,
-std=gnu++20). Host C++ tests under nisps/build still pass (3 binaries,
110+ tests). Build script (scripts/build-firmware.sh) updated to point
at the new sketch path; mode-rewrite logic unchanged.

Closes meml-gkm.
2026-04-29 17:05:38 +03:00
w1n5t0n
6b26168a29 Preserve firmware variant capitalization 2026-04-16 00:46:02 +09:00
w1n5t0n
39312a0d1f Add firmware variant selection to build scripts 2026-04-16 00:37:58 +09:00
w1n5t0n
314408aba9 Add firmware helper scripts and docs 2026-04-16 00:32:32 +09:00
w1n5t0n
e28c76535b docs: update CLAUDE.md with WASM engine architecture, testing, and debug probe
- Add WASM ML Engine section documenting the dual-instance architecture
  (main thread for inference, worker for training), all C bindings, and
  the Dataset/computeWeights JS layer
- Add Debug Probe section documenting window.__nisps API
- Add Testing section with Playwright e2e test infrastructure
- Update output modes (now 4: visual, synth, MIDI CC, audio canvas)
- Document known issue: double loss scaling (meml-ues)
- Note batch inference support in input-heatmap.js
2026-04-03 17:40:12 +01:00
w1n5t0n
1f21494dee feat(playground): implement Phases 2-4 of control surface spec
Phase 2 — Pinning + History:
- snapshot-stack.js: ring buffer (20 max) with auto-snapshot on
  train/randomize/thumbs-down, multi-level undo, tagged entries
- ab-compare.js: A/B weight state comparison with capture/toggle/accept/revert
- region-pin.js: pin rectangular input-space regions (Approach A: example
  pinning), pinned examples always included in training
- param-pin.js: per-output pin flags, pin mask skips pinned nodes in moveWeights
- phase2-ui.js: undo button with history popup, A/B toggle, long-press region
  pin, double-tap param pin
- Modified mlp.js/iml.js/nisps-wasm.js to accept outputPinMask in moveWeights

Phase 3 — Input Refinement + Exploration:
- pressure-feedback.js: touch force + hold duration → intensity multiplier
- auto-explore.js: automated thumbs-down at configurable interval, zoom-scaled
- input-heatmap.js: 16×16 MLP sampling, 3 color modes (luminance/variance/
  divergence), zoom-aware resampling, offscreen canvas rendering
- phase3-ui.js: auto-explore toggle with progress ring, heatmap eye icon,
  pressure indicators, settings drawer section
- joy-map-enhanced.js: added setHeatmap() for background layer rendering

Phase 4 — Output Pipeline + Visualization + Polish:
- output-pipeline.js: global curve → smoothing → slew rate → freeze gate
- weight-health.js: weight magnitude histogram, dead/saturating/healthy status
- gradient-flow.js: per-layer weight-delta analysis, vanishing/exploding detection
- session-presets.js: save/load full state, URL sharing via compact params
- phase4-ui.js: freeze button, network health panel, session preset UI

All phases merged into a-app.js with proper integration: auto-snapshots,
pressure-modulated RL, heatmap triggers, output pipeline in routeOutputs,
gradient capture around training, persistence for all new state.
2026-03-26 10:48:12 +02:00
w1n5t0n
73eeaac0cc feat(playground): implement Phase 1 control surface — compound axes, input pipeline, enhanced joy-map
Three new standalone ES modules + integration into a-app.js:

- input-pipeline.js: 5-stage processing (deadzone → zoom → curve → smoothing →
  momentum-as-zoom), 3 anchor modes, zoom-at-zero freeze, per-axis overrides
- control-surface.js: compound axes (Boldness/Memory/Precision) with interpolation
  tables, offset-based override resolution (trim-pot model), 6 built-in presets
- control-surface-ui.js: floating bar axis sliders, gear icon settings drawer with
  Input/Training/Exploration/Output sections, log-scale sliders, override dots
- joy-map-enhanced.js: zoom minimap with adaptive grid (4×4→32×32), vanishing trail
  with Catmull-Rom spline + tap-to-return, dual concentric noise rings, frozen overlay

Integration fixes from fresh-eyes review:
- getCurrentInputs()/setCurrentInputs() use cached pipeline coords (not raw)
- CSS noise ring hidden when canvas version active (no doubling)
- Input mode switch re-runs through pipeline
- Control surface state persisted to localStorage

Implements full Phase 1 of SPEC-controls.md plus bonus items from later phases
(zoom-aware feedback, control presets with override resolution, input curve/deadzone/
smoothing/momentum all wired).
2026-03-26 10:24:24 +02:00
w1n5t0n
8a550361ea feat(playground): add tiered synth parameter preset system
4 tiers of progressive complexity (Beginner 15 params → Expert 126),
13 presets total with per-param min/max/curve overrides that bias
distributions without clamping extremes. Preset dropdown in UI,
persisted to localStorage, supports ?preset= URL param.
2026-03-23 00:50:56 +02:00
w1n5t0n
3db90b035a feat(playground): add spread param for sigmoid saturation control and fix randomise sync
Add ?spread=0-1 URL param that controls weight initialization scaling,
RL noise scaling per layer, noise cap, and weight decay to prevent
sigmoid output saturation. At spread=0 (original behavior) weights are
uniform [-1,1] and outputs polarise near 0/1. At spread=1 weights use
Xavier scaling (1/sqrt(fan_in)), noise is proportionally reduced, and
10% weight decay per thumbs-down prevents unbounded magnitude drift.

Also fix randomise to re-inject current joystick position and re-run
inference before routing outputs, eliminating the jump on first
joystick move after randomise.

Defaults: tame=1, spread=0.6 across all app variants.
2026-03-22 02:10:26 +02:00
w1n5t0n
c3577be42c docs: update CLAUDE.md and playground README for 126-param C15 map
Document the expanded parameter map, MLP architecture, exclusion
rationale table, and synth mode in both project-level and playground docs.
2026-03-21 23:11:45 +02:00
w1n5t0n
6187a4b4ae playground: add orbiting repulsor field controls 2026-02-11 15:50:06 +00:00
w1n5t0n
0498bbe371 playground: add inertia and drag velocity memory 2026-02-11 15:48:34 +00:00
w1n5t0n
06833cdd19 playground: add blended advection modes 2026-02-11 15:47:13 +00:00
w1n5t0n
97acfd2824 playground: add particle lifetime and respawn modes 2026-02-11 15:45:50 +00:00
w1n5t0n
0550088516 playground: add attractor and dispersion controls 2026-02-11 15:44:33 +00:00
monkey-w1n5t0n
57aae34870 feat: add web-based interactive playground for NISPS
Faithful JS port of nisps-core MLP + IML engine with a touch-friendly
UI for exploring neural parameter mapping visually. Two learning modes:
example-based (set slider targets) and RL feedback (thumbs up/down with
exploration noise). Flow field particle system controlled by 8 MLP outputs.
2026-02-11 13:17:17 +01:00
monkey-w1n5t0n
be85a5cd71 feat: extract nisps-core platform-agnostic ML library
Extract the interactive machine learning engine from MEMLNaut-NISPS
firmware into a standalone, platform-agnostic C++20 header-only library.

What is nisps-core?
-------------------
NISPS (Neural Interactive Shaping of Parameter Spaces) core is a
parameter mapping engine. It takes N input parameters (joystick,
sensors, audio features) and maps them to M output parameters through
an interactively-trained neural network.

Use it to control: synthesizers, effects, lights, robots, game
parameters, or anything that responds to continuous control data.

Key Features
------------
- Header-only: No compilation needed, just include and use
- Platform-agnostic: Pure C++20, works anywhere
- Zero dependencies: Only standard library
- Interactive learning: Train by demonstration
- Lightweight: ~3,500 lines of optimized neural network code
- Flexible: Map 1-100 inputs to 1-100 outputs

Architecture
------------
Core components:
- IML: High-level interactive ML interface
- MLP: Multi-layer perceptron (feedforward neural network)
- Dataset: Training data management with replay memory
- Layer/Node: Neural network building blocks
- Loss: MSE and categorical cross-entropy functions
- Utils: Activation functions (sigmoid, ReLU, tanh, etc.)

Transformations Applied
-----------------------
 Removed Arduino/RP2040 dependencies (Serial, SD, Pico SDK)
 Removed audio synthesis code (nisps-core is control-only)
 Added nisps namespace to all code
 Converted to header-only library with _impl.hpp pattern
 Updated to C++20 (required for std::span)
 Removed platform-specific serialization
 Replaced debug macros with no-op stubs
 Added comprehensive documentation and examples

Files Added
-----------
- nisps-core/README.md: Complete documentation and API reference
- nisps-core/CHANGELOG.md: Version history and migration guide
- nisps-core/include/nisps/*.hpp: 13 header files (~3,500 lines)
- nisps-core/test/main.cpp: XOR test demonstrating basic usage
- nisps-core/examples/simple_mapping.cpp: Interactive demo
- nisps-core/CMakeLists.txt: Build system for tests

Testing
-------
 Compiles with GCC 14.2 (C++20)
 All tests passing
 Successfully instantiates networks and runs inference

Performance
-----------
- Inference: 1-10 µs for small networks (2-10-10-4)
- Training: 10-100 ms for 100 examples, 1000 iterations
- Memory: ~1 KB per hidden neuron

Migration from Embedded IMLInterface
------------------------------------
Old (embedded):
  IMLInterface iml(n_inputs, n_outputs);

New (nisps-core):
  nisps::IML<float> iml(n_inputs, n_outputs);

All method names remain the same, just add the namespace.

Related
-------
- Implements: NISPS_CORE_EXTRACTION_PLAN.md
- Task graph: NISPS_CORE_TASKS.md
- Origin: MEMLNaut-NISPS firmware
- Docs: https://musicallyembodiedml.github.io/memlnaut/

Co-authored-by: Claude Code <claude@anthropic.com>
2026-02-08 17:47:23 +01:00
monkey-w1n5t0n
5dd7029643 add CLAUDE.md for AI assistant context 2026-02-08 15:49:16 +01:00