Button with four values - routing values to buttons through script or module?

Hi there,

since this is my first post here: hi to everyone. And a special thanks to you jean-emmanuel for bringing this great software to live.

This forum ist great and i have alreay learned much from surfing different posts. But for this one i can't find a solution (or understand how i could achieve this), although there is one, and i think a very easy one.

So i'm in the process to create a step sequencer for Redrum (drum computer from Propellerhead Reason). For every drum step you have 4 velocity values: off, soft, medium, hard. Since a toggle button has only 2 values, i managed to get feedback working by making a script widget and alter the parameters of the button (value and color):

if (value === 1)
{
  setVar('channel', 'on_value', "1")
  setVar('channel', 'colorWidget', '#ffff00')
}
else if (value === 2)
{
  setVar('channel', 'on_value', "2")
  setVar('channel', 'colorWidget', '#ff9500')  
}
else if (value === 3)
{
  setVar('channel', 'on_value', "3")
  setVar('channel', 'colorWidget', '#ff4800')    
}

So far so good. Problem is: i have 192 buttons and i don't want to create 192 script widgets. So i think there should be 2 options:

  1. Create a module which routes incoming values and modify button values
  2. Create a module which routes all data (channel, cc, value) to one script and alter the buttons from there.

I looked here: Documentation - Midi Routing and tried a few things but ended up in recieving no data at all or in generating unlimited feedback, which then crashed loopMIDI.

Server midi options: sysex loopMIDI:1,2
Script listens on /debug
Am i on the right way here?

module.exports = {
    oscInFilter:function(data){
        var {address, args, host, port} = data
    
        if (host === 'midi') {
            if (address === '/control') {

                var [channel, ctrl, value] = args.map(arg=>arg.value)
                send('midi','loopMIDI', '/debug', ????????? );
            }
            return // bypass original message
        }
        return {address, args, host, port}
    }
}

Is it possible in general to send three values to a script?

Thank you.

I think the function you want to use is receive(), not send().

Alternatively you could create a custom button with a canvas widget, that does what you want, here is a basic example:
canvas_4state_button.json (2.3 KB)

Hi jean-emmanuel,

thank you for the fast reply.

In your example the canvas works fine as a touch button, but i need a toggle button. BUT... after trying a little bit with your code, i got it to work (don't know if there's an easier way i'm really new to JS and so i don't have much experience in code)..

I reworked the "onTouch" section to this:

if (event.type == 'start')
{
  if (value === 0)
    set('this', 1)
  else if (value === 1)
    set('this', 2)
  else if (value === 2)
    set('this', 3)
  else if (value === 3)
    set('this', 0)
}
else if (event.type == 'stop')
  if (value === 0)
    set('this', 0)
  else if (value === 1)
    set('this', 1)
  else if (value === 2)
    set('this', 2)
  else if (value === 3)
    set('this', 3)

The widget now works bidirectional as i wanted to.

Also i managed to create a module:

button with 4 states and script.json (3.0 KB)
test.js (680 Bytes)

Routing is really easy. All incoming MIDI control messages are filtered. My drum computer sends on channel 1, cc0. If channel and cc matches, the value will be forwarded to a script, which listens on osc address /debug. There, the button value, the button on value and the button label will be modified with the received value.

Again, thank you jean-emmanuel for your kind help, i learned much from it :slight_smile: