Iterating over samples in a frame

Hi,

I’m not entirely sure how possible this is in FrameLib, or whether this is the sort of thing I need to develop an external for, but I’ve been hoping to use framelib to quickly prototype signal processing chains; A large part of this would involve performing operations over samples of a frame directly. I’ve seen that there is the “Vector” objects section of FL that provides some really nice high level operations but I’m wondering if it’s possible to develop lower level functions of my own. For example, I would like to be able to implement a cumulative summing operation, similar to that implemented in Numpy for Python (https://numpy.org/devdocs/reference/generated/numpy.cumsum.html). To do that I would need to iterate over every input sample of a frame, adding the value to all previous and outputing the results as a frame. Would this involve breaking every frame down into single sample sub-frames or…? I’m a little lost on where to get started with this so any advice on the prefered way of achieving this in FL would be really appreciated!

There is no object or series of objects that can simply construct the processing chain you desire and you are right that you would need to go toward extending FrameLib to make your own fl.cumsum~.

fl.nonzero~ in the code is a good place to start (in fact that is the reference @a.harker pointed me toward for making my own first object).

The bit to look at is the process() function which takes care of getting inputs and allocating outputs along with the appropriate sizes.

I’m not sure if this is correct but it would probably look something like this. Perhaps @a.harker can chime in on what would be a better way of doing this.

void FrameLib_CumSum::process()
{
    unsigned long sizeIn;
    

    const double *input = getInput(0, &sizeIn);

    unsigned long sizeOut = sizeIn - 1; // Not sure if this is how this works to be honest

    requestOutputSize(0, sizeOut);
    allocateOutputs();

    double *output = getOutput(0, &sizeOut);

    if (output) 
    {
        for (unsigned long i=1; i < size; i++) 
        {
            output[i] = input[i] + input[i-1]
        }
    }
} 

Ok sure, looks like I’ll need to brush up on my C++ then. I’ve begun adapting the code as you suggest and everything looks pretty straight forward. The only thing I’m not sure of now is how I would go about debugging an object I write before dropping it into Max. Ie is there some sort of unit tests or anywhere where I could chuck in a single frame (for example) so that I could drop in breakpoints and walk through my code to find bugs? Or maybe it’s possible to have an external debugger while running the object in Max? (apologies, I’ve got little experience in max object authoring so I’m not totally sure of the typical workflow)
Thanks so much for the quick help by the way!

The debugging isn’t easy. The best way to do it is to, using Xcode terminology, run with a target that is just your new object (so it doesn’t rebuild all of FrameLib). It will then rebuild the object and open Max with the output piped into the Xcode terminal showing you any errors that way. You could just run Max.app from the command line to see the errors too.

AFAIK though there is no testing framework right now for Max which makes it pretty hard but your object is quite simple in theory and I think most of the code is actually already there disregarding FrameLib style or optimising that loop out. Your big task is to get it to build which is where trial and error and asking more questions will help. Feel free to buzz me!

So unfortunately I’m forced by work to do all my development on Windows, so I’m working using the Alex’s Visual Studio solution rather than the Xcode project to build all of this. The good news is I’ve managed to get an FL object built and running as expected by adapting the NonZero~ object as you suggested. The issue I’ve now got is that although when building for release the FL objects work as expected, adding an FL object (such as NonZero) with debug symbols seems to lock up Max completely. I’ve tried multiple sequences of things like attaching to the Max process through visual studio first then creating the object, or creating the object and then attaching the debugger via visual studio, but none of these generally seem to work. Oddly once it did work, Max didn’t crash and I was able to put a breakpoint in the process method. So I’m sure this is possible, but I don’t know what I did differently to allow this.
Also, I realise this seems like overkill for a simple cumsum object, but the plan is to develop some significantly more complex objects where I’ll need more heavy duty debugging tools than just print statements.

That is not something I’ve come across personally. Alex put together the VS solutions and I barely touch VS for any low level work so I can’t really help you there. Does the problem go away for release builds? That would get you as far as being able to test the object with ins and outs and no crashes. Unfortunately I’d have to defer to @a.harker or even @o.green on how to deal with crashy C++ things.

Yes, the release build works absolutely fine so I can carry on working with that for now. Worst case I’ve got OSX installed on an older PC so could possibly switch to development in Xcode if there’s no other option but would be great if anyone has any ideas what’s causing this. Thanks!

The assumption (rightly or wrongly) that I make in FrameLib at the moment is that all your frame lib objects are compiled in the same way, and thus they can internally treat pointers as pointing to the same kind of thing. If different objects aren’t compiled in the same way that might not be true and two blocks of code might make different assumptions about the nature of an object with a given pointer. On windows that includes using different runtime libraries (windows is not my favourite, and also it’s possible I don’t get everything right on windows). Thus, my assumption is that the best solution to your problem is likely to build all of frame lib in debug mode and use that whilst debugging. If that doesn’t work I can dig deeper.

There are pros and cons of the approach I’m taking. The pros are basically that all frame lib objects are fully separable. The cons are that all the basics of frame lib are baked into every object, and if they don’t match then bad things happen. I might consider a different approach to this, but for now that is how things work.

Another thing I might do is add some kind of testing so max can tell you when objects are incompatible, but that would require things to be a lot more stable.

Ah ok, yes this appears to have fixed the problem and now debugging is working correctly. I think now I understand where I was going wrong it doesn’t seem at all unintuitive to need to build the whole library as either release or debug. Thanks for all the help!