Forum
    • Categories
    • Register
    • Login

    [Bug] Enabling NUM_HARDCODED_FX_MODS breaks custom C++ nodes.

    Scheduled Pinned Locked Moved Bug Reports
    1 Posts 1 Posters 23 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • griffinboyG
      griffinboy
      last edited by griffinboy

      Hardcoded Master FX parameter modslots can force c++ Third-party node parameters to max

      *I used ChatGPT to help format this bug report so that it's written clearly and thoroughly.
      I apologize for the "Ai aesthetic" residue that leaves behind.

      Branch: I'm on the latest HISE develop branch, pulled and compiled today
      OS: Windows 11
      Juce: I'm using Juce 6 (version: 6.1.3)
      Project flags:

      NUM_HARDCODED_FX_MODS=8
      NUM_HARDCODED_POLY_FX_MODS=8
      

      Summary

      I think there is a bug in the hardcoded Master FX "parameter-modslot" path.
      I didn't want to post a report until I was sure it wasn't my own mistake, but I've been reading the Hise source all day and testing different C+ nodes and in the end I concluded this might be a bug:

      If a third-party node exposes a parameter modslot with ConnectionMode::Parameter , loading that node into a hardcoded Master FX forces the modslot parameter values to get set to the top of their ranges (and stuck there).

      This is not a small issue. For DSP nodes it completely breaks effects, and means you can't use any c++ nodes that have modslots inside monophonic hardcoded master FX.

      I like almost all of my c++ nodes to have modslots so that they can work easily with hise modulation and the matrix modulator. This bug means I have to make modslot and non-modslot versions of every effect, so that I can load the modslot version into poly contexts and the non-modslot one into mono contexts. And then for the mono nodes I have to use a different modulation scheme. Messy.
      (unless I'm misunderstanding something).

      How I found it

      I was testing a compiled third-party DSP node.

      The same node behaved normally in a ScriptFX context, but in a hardcoded Master FX it produced broken / glitchy / extremely wrong output.

      When I removed these project flags and rebuilt, the hardcoded Master FX version started behaving normally again:

      NUM_HARDCODED_FX_MODS=8
      NUM_HARDCODED_POLY_FX_MODS=8
      

      So the issue appears to be tied to hardcoded FX modslots.

      Disabling those flags is not a usable workaround for me, because then hardcoded modslots would be unavailable project-wide.

      Minimal test

      I made four tiny diagnostic third-party nodes.

      Each node has one parameter:

      Parameter_name: ProbeValue
      
      Range:   0.0 to 1.0
      Default: 0.25
      

      Each node outputs a tone whose gain follows ProbeValue.

      Expected result: quiet tone.
      Bug result if the parameter is forced to max: much louder tone.

      Each node exposes the same parameter slot:

      modulation::ConnectionInfo slot;
      slot.connectedParameterIndex = ProbeValueParameter;
      slot.connectionMode = modulation::ConnectionMode::Parameter;
      slot.modulationMode = modulation::ParameterMode::ScaleAdd;
      

      I tested four variants:

      Griffin_ModSlotProbe_NoHandle
      Griffin_ModSlotProbe_WithHandle
      Griffin_ModSlotProbe_FrameHandle
      Griffin_ModSlotProbe_ModNodeHandle
      

      These check whether adding the following details would fix or change the behavior:

      • no handleModulation() function defined
      • handleModulation(double&) { return 0; }
      • block processing forwarded through processFrame() from process()
      • isModNode() == true (yeah, I know that's not going to do anything)

      Result

      In hardcoded Master FX:

      NoHandle       left loud, right silent
      WithHandle     left loud, right silent
      FrameHandle    left loud, right silent
      ModNodeHandle  left loud, right silent
      

      The left channel becoming loud proves ProbeValue was driven from 0.25 to 1.0.
      And the right channel staying silent means handleModulation(double&) callback was not called.

      Expected behaviour

      Ideally, a hardcoded Master FX parameter modslot should not push a node parameter to its maximum value simply because the slot exists.

      If no meaningful modulation value is active, the parameter should keep its current/default value, or the slot should not be treated as connected until there is an actual usable modulation connection.

      Current behaviour

      Currently, with hardcoded FX modslots enabled, a third-party C++ node exposing ConnectionMode::Parameter can get seemingly spammed with max-range parameter values during rendering / stuck at max value (moving the parameter doesn't unstick us, the parameters are stuck to max).

      Why this matters

      I'm assuming that HISE nodes are intended to be modular.
      If that's true, then a node that is poly-capable, or a node that exposes modslots, should be able to function in a mono hardcoded Master FX context too.

      This is also inconvenient for my shipped products. A HISE user can load one of my nodes into HISE and get broken DSP because the hardcoded Master FX modulation path corrupts parameter values.

      The result of all this is that ConnectionMode::Parameter becomes unsafe for third-party hardcoded Master FX products.

      Suspected source bug

      The Hise algorithm seems to do something like this:

      HardcodedMasterFX::applyEffect()
        -> extraMods.processChunkedWithModulation(rd)
        -> ExtraModulatorRuntimeTargetSource::handleModulation(...)
        -> ModChainWithBuffer::getOneModulationValue(startSample)
        -> rd.handleModulation(pIndex, mv)
        -> parameter range convertFrom0to1(mv)
        -> p->callback.call(value)
      

      The important part is in the hardcoded Master FX context, with no active voice state, getOneModulationValue() can return an inactive/default modulation value of 1.0f.

      That normalized 1.0 is then converted through the parameter range, so the node receives the parameter maximum.

      Request

      Could the hardcoded Master FX parameter-modslot path be changed so inactive / unconnected / not-yet-valid modulation does not force parameter-mode slots to max?


      post script: a similar / related bug exists in the Hise synth group, I will write a report on that after a bit more investigation.


      Christoph, Thanks for all your hard work🫔

      1 Reply Last reply Reply Quote 0
      • First post
        Last post

      8

      Online

      2.4k

      Users

      13.8k

      Topics

      120.4k

      Posts