memlnaut-nisps/playground/js/synth
monkey-w1n5t0n b290144670 fix(modular): base_amp floor + opt-in matrix to keep voice audible
Modular sub-engines computed amp_val as a pure function of mod_amp (the
matrix d08_amp destination sum), so once the MLP drove the matrix cells
every joystick movement had a chance to silence the voice: matrix cells
have signed range [-1, 1], sigmoid outputs near 0.5 denormalise to 0,
and the amp gate collapsed. Additive survived in scattered regions
because it only has one kill-switch (d08_amp); subtractive and fm were
almost always dead because they also have d05_cutoff and d01_op1_level.

Two changes:

1. DSP: each sub-engine gets a base_amp hslider (default 1.0) so
   amp_val = clamp(base_amp + mod_amp) * level * vel_gain. At the
   default the voice is always fully open and d08_amp modulation is
   purely additive decoration; drop base_amp to 0 for classic
   ADSR-gated VCA behaviour.

2. ModularEngine._rebuildParamMeta: restore the _exposedMatrixCells
   gate (default empty). paramCount drops from 512 to 32 (4 ADSR * 4
   + 8 LFO * 2); matrix cells are opt-in via setExposeMatrixCell.
   _applyDefaultPatch no longer writes s00_d08_amp since base_amp
   keeps the voice audible without routing.

Tests updated for the new 32-param baseline; matrix-cell persistence
test now calls setExposeMatrixCell(1, 5, true) before asserting the
cell lands in paramMeta. Drive-by: engine-switching test bumped from
3 to 4 engine cards (stale since the modular engine was added).
2026-04-11 09:27:19 +02:00
..
additive-engine.js feat(playground): Additive + FM engine integration, live engine switching (meml-mdy, meml-355) 2026-04-03 17:56:35 +01:00
additive-presets.js feat(playground): per-engine param presets for additive + FM (meml-ax4) 2026-04-03 18:26:12 +01:00
arpeggiator-worker.js feat(playground): engine abstraction layer + C15 adapter (meml-byk) 2026-04-03 17:30:28 +01:00
arpeggiator.js feat(playground): engine abstraction layer + C15 adapter (meml-byk) 2026-04-03 17:30:28 +01:00
c15-adapter.js feat(playground): EOC chain wired into audio graph, bypass mode manual sliders (meml-xp3) 2026-04-03 17:49:14 +01:00
c15-bridge.js feat(playground): EOC chain wired into audio graph, bypass mode manual sliders (meml-xp3) 2026-04-03 17:49:14 +01:00
engine-interface.js feat(playground): Faust WASM build pipeline + param auto-discovery (meml-5s3) 2026-04-03 17:30:23 +01:00
faust-engine-base.js fix(playground): FaustEngineBase creates AudioContext if none passed; add stop()/start() methods 2026-04-03 19:08:52 +01:00
faust-param-meta.js feat(tests): add 24 Playwright e2e tests for engine switching + fix hidden param filtering 2026-04-03 19:28:23 +01:00
fm-engine.js feat(playground): Additive + FM engine integration, live engine switching (meml-mdy, meml-355) 2026-04-03 17:56:35 +01:00
fm-presets.js feat(playground): per-engine param presets for additive + FM (meml-ax4) 2026-04-03 18:26:12 +01:00
midi-input.js fix(playground): decouple MIDIInput from C15Bridge — use SynthEngine interface (meml-se4) 2026-04-03 18:20:29 +01:00
modular-engine.js fix(modular): base_amp floor + opt-in matrix to keep voice audible 2026-04-11 09:27:19 +02:00
modular-presets.js feat(playground): add Modular audio mode with shared mod pool 2026-04-11 07:34:41 +02:00
osc-output.js feat(playground): add OSC output bridge for external synth control 2026-03-25 11:55:58 +02:00
param-map.js feat(playground): add synth parameter tooltips, group drawer with per-param curve/mute controls 2026-03-22 21:57:21 +02:00
presets.js feat(playground): add tiered synth parameter preset system 2026-03-23 00:50:56 +02:00