C++ compiled custom operator CHOP behaves 'glitchy' by adding extra samples

Dear all,

I’ve compiled a .dll file based on the BasicFilterCHOP sample file. It’s a simple ‘gate’ behavior CHOP that flicks to ‘1’ when a predefined value has been reached.

What I’m noticing is that when it gets an input with one channel and 1 sample, for instance an lfoCHOP, it occasionaly glitches,

as in it adds extra samples for a very short amount of time.

I’ve set the timeslice bool to off, so I’m not sure why it behaves like this.

Best regards,

Stefan

BasicFilterCHOP.zip (1.6 KB)

If you have timeliced turned to off, it’ll still match the channel length of the input chop as specified by ginfo->inputMatchIndex in BasicFilterCHOP::getGeneralInfo(), by default.

If you want control over the length of the channel, you need to do so via BasicFilterCHOP::getOutputInfo()

Thank you for your reply. That works as expected correctly.

But for instance when I input an lfoCHOP with only one channel with one sample changing in value, it still jumps now and then to one channel with additional samples.

It’s hard to capture the moment, since it really occurs randomly and only a fraction of a second.

The LFO CHOP is timesliced, so it may have more than one sample, depending on if you drop a frame. If you middle click on the node and look at it’s channel length, you may see it jump to 2 (or more), if you drop a frame.
You can use a Hog CHOP to force dropping frames.

Can you post your latest version of the code?

Hi, the .zip file in my first post includes the .cpp file. I’ve added this screenshot for clarification.

When I for instance add a limitCHOP, it stays/shows 1 channel constantly, no matter how far I push the hog. Could it be that the grayed out ‘timeslice’ switch on the GateCHOP (my compiled CHOP) is still on? Or the fact that it’s grayed out, it’s off by default. I can’t recall I’ve set timesliced to ‘true’.

The .zip file in the first post doesn’t include my suggested edits from my first reply though. Can you please post the .cpp with those edits included?
The Limit CHOP is coded to only output 1 sample when timeslice is off. By default a C++ CHOP is not coded that way, you need to add code that does that.

Thank you for you insights, I’ve eventually changed in into:

BasicFilterCHOP::getOutputInfo(CHOP_OutputInfo* info, const OP_Inputs* inputs, void*)
{
    const OP_CHOPInput* input = inputs->getInputCHOP(0);
    if (input) {
        info->numChannels = input->numChannels; 
    }
    else {
        info->numChannels = 0; 
    }
    info->numSamples = 1; 
    return true;
}

The only thing I’m very curious about is why for instance a limitCHOP would only cook .003 ms compared to ‘my’ compiled gateCHOP that cooks .018 ms.

void BasicFilterCHOP::execute(CHOP_Output* output, const OP_Inputs* inputs, void*)
{
    // Get the value of the "Gate" parameter.
    double gate = inputs->getParDouble("Threshold");

    // Get the first input CHOP.
    const OP_CHOPInput* input = inputs->getInputCHOP(0);

    // If there is no input or the input has no channels/samples, do nothing.
    if (!input || input->numChannels == 0 || input->numSamples == 0)
        return;

    // Process each channel in the input.
    for (int i = 0; i < input->numChannels; ++i)
    {
        // Get the first sample of the current channel.
        double value = input->channelData[i][0];

        // Apply the step function: output 1.0 if value > gate, otherwise 0.0.
        output->channels[i][0] = static_cast<float>((value > gate) * 1.0);
    }
}

There is more overhead involved in the C++ interface, so a single sample will be more expensive. If you are doing something with 1000 samples the times should be more similar