Articles

    RNBO and gen~


    RNBO, released this past month, is the new kid on the block for Max code generation. At first glance, you may be tempted to think that gen~ and RNBO are kind of the same thing. After all, both prominently feature “code generation.” You patch together objects in a Max-like way, and something magical is waiting behind the scenes, ready to compile your patch and stick it into the Max audio graph. Even cooler, you can get a C++ code export from your patch and use it separately from Max!
    So in a world with both gen~ and RNBO, how do the two coexist? In this article, I’ll break down the intertwined goals and purposes of both technologies.
    A gen~ patch works identically in Max and in RNBO.
    A gen~ patch works identically in Max and in RNBO.

    Processing buffers and processing samples

    Like Max and most audio applications, RNBO works on chunks of audio data, sometimes called buffers or signal vectors. This technique of I/O buffering improves performance but makes it either difficult or impossible to implement DSP algorithms using just built-in Max or RNBO objects. This is because with many DSP algorithms (like filters, choruses, reverbs, oscillators, or physical models, to name a few), you will need things like single-sample feedback loops. (Note: This is a slight simplification. Two exceptions to the "RNBO is vector-processing only" rule are with RNBO's expr~ and the codebox~ operators which do allow you to work at the single-sample level. See more about RNBO codebox~ in the docs!)
    Fortunately, single-sample processing is what gen~ was made for. Since Max and RNBO both need single-sample patching environments, gen~ is available for both!
    A somewhat subtle beauty of this is that all of the custom gendsp you’ve written or collected over the years translates directly to RNBO and “just works.” Not only is gen~ cross-platform (you don’t need to compile gen~ separately for Windows or Mac like you would with an external), but it is cross-environment between Max and RNBO. Further, with the @exposeparameters 1 attribute for gen~ inside RNBO, you don’t need to do any extra work to have gen~ parameters show up in RNBO exports! (For more information, see the official documentation on gen~ inside RNBO.)

    Bringing code generation to more familiar places

    The first release of gen~ occurred in 2011, and it was the first time code generation was possible in Max. Exporting this generated code was a “bonus feature” that wasn’t the original purpose of gen~, but it inspired a number of projects like the Electrosmith Daisypatch Oopsy package and the gen~ plugin export JUCE wrapper.
    Gen made clear the power of code generation, and it was the first step towards solving what folks at Cycling ‘74 refer to as the “trapped in Max problem.” The problem was that gen~ is specialized to solving problems of lower-level DSP prototyping, and doesn’t contain UI objects, MIDI I/O, or other higher-level objects like anti-aliased oscillators, FFTs, filters, and more.
    With RNBO, code export, not just code generation, is a guiding design principle. This separation of concerns between RNBO and gen~ is key in understanding their relationship – by letting RNBO focus on being a friendly and familiar patching environment, gen~ doesn’t need to expand to include MIDI or event processing.
    At the same time, RNBO doesn’t need to dip down into the low levels of single-sample processing because, well, gen~ is just there!

    by Isabel Kaspriskie on
    Nov 30, 2022 10:04 PM