Files
feuerwerk/tools
adminandClaude Opus 5.5 d844f2734a Add an Acid instrument node for TB-303 style bass lines (#421)
The instruments could only come near a 303 with a Chip, a Filter and
two envelopes. The biquad filter does not saturate, every note strikes
anew, and there was no slide and no accent.

- Acid is a new instrument node that plays a saw or a square through a
  four-pole ladder low-pass with tanh saturation, oversampled twice.
  Knobs: cutoff, resonance, env mod, decay, accent, tuning and slide
  time.
- An accent comes from the velocity, from 0.9 on. It is louder, opens
  the filter further with a shorter decay, and accents close behind
  each other build up.
- Two notes that touch or overlap slide. Each note stays a voice of
  its own, so the scheduler is unchanged. The notes of a line share
  one synth in the worklet, and the new voice takes it over from its
  first sample on.
- The node sets its own volume, so it needs no envelope behind it.
- The graph shows it as a device with the filter curve at rest and at
  the top of the sweep.
- A preset Acid Bass puts an Acid in front of a short echo.

Tests:
- tsc, eslint, Prettier clean
- Unit: 14 new tests in acid.test.ts for pitch, low-pass, resonance,
  sweep, accent, slide and the handover between two voices.
- e2e 34 on melektaus-atx: ALL PASSED, 148 checks (3 new). The
  handover sits on sample 4800 and jumps by 0.0012, of three notes
  only the second slides.
- Without the handover, or with a slide that strikes anew, the unit
  tests are red.
- Gate on melektaus-atx: tsc, eslint, Prettier clean, 4753 of 4754
  tests green. The red one was sound-library.test.ts, which did not
  know the new slid count in the stats. Fixed, and the file alone
  is green again with 128 tests. No second full gate.
- Not checked: the sound by ear, slide at the keyboard, a bake with
  Acid, the CPU load of many notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 11:08:57 +02:00
..
Plugins belong to the project, and they load before it: the project file gained the field plugins: ["demo-plugin.js"] (default empty, no formatVersion bump), the Plugins tab's switch writes into it as an ordinary undo step (SetPluginActiveCommand) instead of into a server-wide plugins.json, and the start order is turned around - startPlugins only fetches the list of files, then editor.boot() runs and ProjectStore.load(id, prepare) hands the raw JSON through before it is deserialized, where pluginsOf(raw) reads the list and PluginManager.syncTo() activates exactly those; that is the point of the issue, because what a plugin registers has to stand there before normalizeGraph would throw it away as unknown (#126, #127), a project switch first stops what the new project does not name and then starts what it does, a file the server does not have is passed over silently, and after signing out the manager is dead so a late event cannot start anything in a torn-down session; on the server plugins.json, PluginStore::setActive, isActive, the route PUT ?r=plugins/{file} and the 403 for inactive modules are gone and GET ?r=plugins only answers {file,bytes,updatedAt}, which makes every plugin file fetchable - the consequence accepted in #117, written down in the wiki for #115 and #116; publishPlugins(root) only copies files now, the seeder switches the demo plugin on in the fixture project, and the Plugins tab carries a puzzle piece as its icon while only a plugin's own tab still goes without one (the knob and the socket are cubic curves, not arcs, which Pixi's parser draws as a spike after an L); 3 new e2e checks in module 38 and 5 new unit tests cover the project as the owner of the switch, its undo, the order, pluginsOf against crude input and an unknown file name (#119)
2026-09-20 14:24:27 +02:00