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).
343 KiB
343 KiB