Custom Module Sliders

I'm starting to learn more about the custom module and I cannot figure out the basics. How can I simply set a faders preargs with a custom module? I want to send multiple preargs with a single fader.

For example: a fader that control cc1 and cc11, or a fader that sends on multiple midi channels etc..

Thanks

Hello,

Here's an example of one fader sending the same value to multiple CCs.
The OSC fader has the following props setup:

"address:  /fader" //this is an arbitrary custom OSC address
"perArgs: [1, 11, 12, 13, 14]" // these are the CC numbers the fader will send message to
"target: midi:none" // this is a dummy midi port name. This message will be caught by the custom module, transformed and bypassed

As you can see, the props are used in a different way.

Now, the custom module looks like this:

module.exports = {

    //this function intercepts all messages the client send and store them in the data argument
    oscOutFilter: function (data) {

        //this is called destructuring, and breaks down the data into those four variables
        const { address, args, host, port } = data

        // checks if the address is the same custom address assigned to the client fader
        if (address == "/fader") {
            // args is an array of objects in the form {type: string, value: number}
            // and the last element is the fader current value
            // here its value is stored in a new variable at the same time
            // it's popped from the original array
            const value = args.pop().value

            //looping through all the remaining elements of the args array
            //that represent all the CCs to send out
            args.forEach(cc => {
                //finally, each CC is sent out with the current fader value
                // replace "midiPortNameToYourDAW" with the midi port used to send midi to your DAW
                send("midi", "midiPortNameToYourDAW", "/control", 1, cc.value, value)
            });
            // after intercepting, transforming and sending the data, the original one is bypassed 
            // by returning nothing inside this if statement
            return
        }

        // outside the if statement, to make sure all the other data still can be sent out
        // the original data must be returned
        return data
    }
}
Files:

fader_multiCCs_custom_module.json (2.3 KB)
custom-module.js (1.6 KB)

Ouch! That's a lot :slight_smile:
This is not the only way of make this work, but I hope it helps you understand custom-module better.
Cheers

3 Likes

Thank you, this has been very helpful. I believe I've managed to adapt this to use a single slider to send on multiple midi channels.

Any ideas of why this isn't working? I have multiple instruments in kontakt, each on a different channel, I want the fader to control the same parameter on all of them.

The debug appears to be correct, but the result is the fader only affects channel 1 in kontakt and none of the others.

module.exports = {

    oscInFilter:function(data){

        var {address, args, host, port} = data

        return {address, args, host, port}
    },

    oscOutFilter:function(data){

        var {address, args, host, port, clientId} = data

        if (address === "/fader") {
            const value = args.pop().value
            for (let x = 1; x <17; x++) {
            send("midi", "OSCMIDICONTROL", "/control", x, 23, value)
        }
            return
            
        }

        return data
    }

}

EDIT: Figured it out, was a DAW issue. Track has to be enabled to receive ANY or ALL midi inputs.

1 Like

Hi @ClelsonLopes

Would you happen to know what's wrong with this? Things seem to work, but I'm getting an error when I click in the project window or press another button widget.


    oscOutFilter:function(data){

        var {address, args, host, port, clientId} = data

        if (address === "/micFaderClose" || "/micFaderTree" || "/micFaderAmbient" || "micFaderOutriggers") {
            const value = args[2].value
            const midiCC = args[1].value
            for (let x = 1; x <17; x++) {
            send("midi", "OSCMIDICONTROL", "/control", x, midiCC, value)
        }
            return
            
        }

        return data
    }

}

Here's what the error says.
image

What's your faders' configuration in OSC? It seems that arg[2] or arg[1] in the custom module is causing the issue.

Here's an example of one. They are all the same, but have a differen't cc number in the preArgs.

The debug shows the faders work properly, just getting the error on other clicks.

Bascially I want these faders to send on all channels, but different cc messages for each.

Ok, that's fine. Try to find some scripting in your OSC session. Or load the session without the custom module and check if you get the error.

What do you mean find some scripting? The error is only present when the custom module is loaded

Here's the file and code for custom module.

Channel Faders.json (20.7 KB)



module.exports = {

    oscInFilter:function(data){

        var {address, args, host, port} = data

        return {address, args, host, port}
    },

    oscOutFilter:function(data){

        var {address, args, host, port, clientId} = data

        if (address === "/sfcsMicFaderClose" || "/sfcsMicFaderTree" || "/sfcsMicFaderAmbient" || "sfcsMicFaderOutriggers") {
            const sliderValue = args[2].value
            const midiCC = args[1].value
            for (let x = 1; x <17; x++) {
            send("midi", "OSCMIDICONTROL", "/control", x, midiCC, sliderValue)
        }
            return
            
        }

        return data
    }

}

Ok, I've spotted something wrong:

It's not possible to check a condition the way you did using || (OR operator). You need to check if the address is equal to each one separately, otherwise it will always evaluate to true.
It should look like this:

if (address === "/sfcsMicFaderClose" || address === "/sfcsMicFaderTree" || address === "/sfcsMicFaderAmbient" || address === "sfcsMicFaderOutriggers")

In a more elegant/readable way:

const fadersAddress = [ "/sfcsMicFaderClose", "/sfcsMicFaderTree", "/sfcsMicFaderAmbient", "sfcsMicFaderOutriggers"]
if (fadersAddress.includes(address)) //...

I think this fixes the issue.

1 Like

Awesome, thank you so much. Very insightful, is odd that the faders appeared to be sending the proper messages.

Anyways, you're right this fixed the error.

1 Like

@ClelsonLopes Don't mean to keep asking you things, have really appreciated all the help you have provided. Would you have any quick info to point me in the direction of including the following feature.

I want to include a button that sends the current value of all 4 faders from this post. But when it sends, it needs to be on all channels like how the faders send.

I've set up a button with address: /sendAllMics but I'm a bit lost in how to script this.

Would I need to store the values somehow or is there a simpler solution?

You're welcome. Thanks for the message :slight_smile:

I think the solution can be done without the custom module.
Just create a button, change its mode to tap and add this code to its onValue prop:

const fadersId = ["fader_1", "fader_2", "fader_3"] //add all the faders id inside this array

fadersId.forEach(fader => {
  set(fader, get(fader))
})

Let me know if it works
Cheers

Brilliant! Yeah it works. Didn't know about forEach, that's awesome.

Is it typical to use both on value scripting and a custom module? Or is it possible to do everything in the custom module?

Well, I like to think the custom module as a complement to the client.
Some things are better to handle in the client only.

The sliders you made using the custom module can do the same thing without it.

But sometimes the client can't do something, so the custom module comes to place (for example, handling incoming NRPN messages)