Found while rendering a sample pack with a headless JUCE VST3 host. Root cause not established, and it may turn out to be host-side rather than a Niner defect — filing because the evidence is reproducible and, if it is plugin-side, it would affect DAW users automating this parameter.
Symptom
Rendering a one-shot from Niner's factory clap preset with a host that sets parameters and then sends a note-on: the clap layer contributes exactly nothing. Three renders are byte-identical (same md5):
Clap = 1.0 (on)
Clap = 0.0 (off)
Clap = 1.0 with Clap Tail at max (400 ms)
Byte-identical on/off means the layer output is precisely zero, i.e. self.clap.trigger() at dsp/engine.rs:404 is never reached, so clap.tick() returns silence forever.
What I ruled out
- Recipe/preset error. The parameter values faithfully match
assets/factory_presets/clap.json: clap_on: True, clap_level 1.5 (normalized 1.0), clap_freq 1130 Hz, clap_tail_ms 155.
- Name or index resolution. A parameter dump reports
43, Clap, 0.000000, Off. The host matches by name, exactly, and warns on failure. No warning was emitted.
- Parameter delivery in general. Changing
Master Volume changes the render.
- Bool parameters in general. Toggling
Comp Limiter changes the render.
- Trigger-time parameters in general. Changing
Decay and Sub Pitch Start, both read at trigger, changes the render.
So the delivery mechanism works for floats, for bools, and for values read at trigger time. clap_on is the one parameter that is both a bool and read at trigger time (dsp/engine.rs:401), which is consistent with it not being true at the instant trigger() runs.
Possibly relevant
The host calls prepareToPlay() after setting parameters, which re-activates the VST3 component before the first processBlock. If nih-plug's wrapper treats a stepped/bool parameter differently from a continuous one across that reactivation, that would explain the asymmetry. I could not confirm this without instrumenting.
What would settle it
A log line for params.clap_on inside Engine::trigger, or a repro in a DAW: automate Clap on, then send a note, and check whether the clap layer fires. If it fires in a DAW, this is a host-side problem and can be closed.
Found while rendering a sample pack with a headless JUCE VST3 host. Root cause not established, and it may turn out to be host-side rather than a Niner defect — filing because the evidence is reproducible and, if it is plugin-side, it would affect DAW users automating this parameter.
Symptom
Rendering a one-shot from Niner's factory
clappreset with a host that sets parameters and then sends a note-on: the clap layer contributes exactly nothing. Three renders are byte-identical (same md5):Clap= 1.0 (on)Clap= 0.0 (off)Clap= 1.0 withClap Tailat max (400 ms)Byte-identical on/off means the layer output is precisely zero, i.e.
self.clap.trigger()atdsp/engine.rs:404is never reached, soclap.tick()returns silence forever.What I ruled out
assets/factory_presets/clap.json:clap_on: True,clap_level 1.5(normalized 1.0),clap_freq 1130 Hz,clap_tail_ms 155.43, Clap, 0.000000, Off. The host matches by name, exactly, and warns on failure. No warning was emitted.Master Volumechanges the render.Comp Limiterchanges the render.DecayandSub Pitch Start, both read at trigger, changes the render.So the delivery mechanism works for floats, for bools, and for values read at trigger time.
clap_onis the one parameter that is both a bool and read at trigger time (dsp/engine.rs:401), which is consistent with it not being true at the instanttrigger()runs.Possibly relevant
The host calls
prepareToPlay()after setting parameters, which re-activates the VST3 component before the firstprocessBlock. If nih-plug's wrapper treats a stepped/bool parameter differently from a continuous one across that reactivation, that would explain the asymmetry. I could not confirm this without instrumenting.What would settle it
A log line for
params.clap_oninsideEngine::trigger, or a repro in a DAW: automate Clap on, then send a note, and check whether the clap layer fires. If it fires in a DAW, this is a host-side problem and can be closed.