Search code examples
midipuredata

Pure Data abstraction to take n arguments


I've created a Pure Data abstraction which takes 5 MIDI controller IDs as arguments, and has two inlets (velocity and MIDI controller). I use spigot to output the input velocity at outlet i if the MIDI controller ID matches the i th argument to the abstraction. Screenshot of Pd patch

I use this to control 5 sliders (volume, attack, decay, sustain, release) from my MIDI controller, which look like this:

enter image description here

As you can see, the abstraction is very repetitive, and ideally it would be able to take n arguments, outputting the slider value of the given MIDI slider at the i th outlet. Alternatively I could just use a single argument and use the abstraction anew for each slider, but that's a bit repetitive too.

Is there a way to take n arguments in my abstraction? Or, is there any other more elegant solution to control sliders from MIDI that I'm missing?


Solution

  • For core vanilla objects or externals it is a common feature to take a variable amount of arguments. Many objects like [trigger], [select], [pack] or [unpack] behave this way and create a number of xlets according to how many arguments they are given.

    For abstractions however, there is no simple way to have a variable number of outputs depending on the number of arguments given. It's possible, but it's rather a hack.

    Let's first look at some techniques to make the patches easier.

    As you can see in the following screenshot the [expr] object in your patch can easily be substituted by a simple Pd object: [==]

    screenshot pf pd patch showing expr isn't necessary

    Let's look at the MIDI messages. MIDI objects output the elements of the hierarchical tree: channel, controller, value in this order but from right to left (true for all objects in Pd, the rightmost outlet fires first). What you want is routing them according to the controller number, ignoring the channel number. For this you need to flip the order of the two first outlets so you can use the controller number as a selector in a list. One way to do this is to pack the numbers and then reorder them in a message using the dollar symbols (careful, dollar symbols in message objects operate on local messages, they have nothing to do with what dollar symbols do in object boxes). Another method would be to use the object [swap] (using [swap] in this case would reduce the number of objects by one in the patch, but the [pack] and [message( is more versatile, that's why I show it here).

    MIDI filtering based on controller number

    Regarding the actual question of taking n arguments to change the number of outlets: This challenge are two separate problems:

    1. How to detect the number of arguments
    2. How to change the number of outlets dynamically

    Until recently there hasn't been a way proper way to detect the existence of arguments. Since Pd 0.50 there is [pdcontrol] which allows exactly this.

    get number of arguments

    Using [initbang] here because [loadbang] would fire too late for creating the outlets. The second part of the challenge may be solved either through a technique called 'dynamic patching' or by outputting a list instead of creating additional outlets. However with a list output you'd need to route it afterwards and then you'll arrive quickly at the patch pictured above.