Max: Procesing buffer~ with MSP objects (hacking)

You can definitely build a patcher on the fly - I’d suggest looking in framelib at the wrapper class to see some useful details and an example of this - somewhere like here:

This might also show you how to get the signals out of a specific object, as I send the audio directly out the wrapper from the hosted object (which needs to be in a patch so max can see it as a normal audio patch.
The dsp stuff is a bit more complex but this might help:

There are some complexities to whether you should report the patch you are hosting as a sub patcher or not, and also you need to prevent it being seen by max for normal audio compilation through some combination of setting it’s association and using dsp_setloadupdate

The comment about reporting sub patchers may not apply in your case - I need max to see it as a subpatcher, but you probably don’t. However, dynamicdsp~ does also do this kind of reporting for a reason I’ve forgotten right now.

Happy to field further questions.

Cheers! I’d managed this afternoon to make a patcher and compile a chain that was getting called when I tickled dspchain_tick, but with no audio vectors being allocated. I’ll have a look at your examples to see if I can make further progress, but the basic idea seems like it has legs…

If you are compiling the patch’s dsp you don’t need to allocate your own audio vectors - you just need to find out how to pass audio in and out. You can do that with dynamic.in~ style objects, or the way the max wrapper works in framelib.

Actually for ins you probably need something like dynamic.in~. For outs you might be able to steal the outputs of the objects without allocating your own. Arguably you might also be able to just make an object in the patch from which you can get the pre-allocated vectors that dsp_compile makes for the connection between this and the object you are interested in.

Yeah, I made a couple of input and output classes after studying dynamic.in~ / out~ this morning – I’m just missing something in my process: although my perform functions are getting called as expected, the double** vectors are null.

I’ll see if associating with the parent patcher of the host object via setassoc and gensym(#P) gets me anywhere

Happy to eyeball the code for any gotchas if you like and can point me to it? (off list if preferable). I presume you are happily connecting the ins/outs?

Also setassoc should be done with your outer object as the owner. #P is different and is used to pass the parent patch down to the patch you are making on load.

The setassoc helped, as did not having the argument for perform in the wrong order :grin: Remaining problems seem to be routine issues of everyday memory corruption and general derpitude, but things are happening that show promise of one day being the right things

Always happy for external eyeballs: https://gist.github.com/weefuzzy/024f8784d0e4d44203e18728e6fb6200

  • Z_NO_INPLACE doesn’t have any effect here as far as I can see in any case.
  • You’ve calculated the remainder, but not just implemented (as I’m sure you know)
  • I can’t see any evidence of memory corruption (except the commented out code) - is there anything else to look at in this regard?
  • The patch owns the objects you’ve put in it, which is why the last bit crashes. (see https://github.com/AlexHarker/FrameLib/blob/276b2fcc708a975eb6120e08162dbc691ae7adb4/FrameLib_Max_Objects/Common/FrameLib_MaxClass.h#L509)
  • To be explicit - in your case freeing one thing (the patch) will free all 4 - you can confirm by putting breakpoints in your objects, but it also follows common sense - when you delete a patch everything in it is freed.

If there is other corruption to investigate then point me to where that might be and my eyeballs will delve further.

Thanks!

Yeah, just wishful keyboard mashing on my part. Because the memory corruption (or not) that isn’t obvious is that the output buffer is currently ending up with Mostly Garbage in (but little snippets of Rightness), plus an occasional sigabort from Max.

The free-ing crash seemed to be when I freed the processor (so before it ever got as far as freeing the patch); just calling object_free on the patch itself is also crashing.

I can’t (yet) see an obvious cause for the garbage in the output (hence resorting to wishful thinking), but I will continue doing slightly random things until I have a better handle on what’s going on.

Oh - now it’s my turn to thank you, because I really enjoyed finding this one.

Maybe take a look at the docs on how memcpy works - what exactly is each argument expecting…

You aren’t in C++ land now…

:wink:

Also I’m guessing that the snippets are - I don’t know, maybe 8 samples long at a time, with 56 samples of wrongness appended in a repeated pattern?

Is the answer 64 * sizeof(double)? :scream_cat:

Is that really a question?

Although this doesn’t explain the sigaborts…

No, even in my befuddled state I can see that writing 64 bytes isn’t What I Meant. Fixing it does make things crash much more reliably though (the sigaborts were from malloc, because I’d corrupted the free store somewhere), now its something similar and memory-stampy. I’ll try not allocating my temporary buffers on the stack as a first stab…

Is the gist up to date? - I’ll give it a compile if you point me to your latest version.

Do you mean in the object struct? I don’t see anything on the stack here. There is/used to be an object struct size limit, but you are well within it here, so I don’t see why that would be an issue.