Generate color from midi message combination

Hello,

Is it possible to make a widget color respond to an RGB-like message, communicated in a midi format?
For example:
Chn 1 Red
Chn 2 Green
Chn 3 Blue

Sending a note with different velocity combinations of these 3 channels would change the color of widget. If its possible, how would the implementation look like? Would it require dynamic css, "just" scripting for these variables, everything?

Thank you

Hi,

There are probably a few ways you can do this. In the CSS property of your widget you can do something like this:

/* background-color: rgb(0,0,0) */
:host {
background-color: #{"rgb(" + OSC{/chn1_Red, 0} + "," + OSC{/chn2_Green, 0} + "," + OSC{/chn3_Blue, 0} + ")}
}

then in your custom module, you'd create a method in the OSCFilterIn to list these channels, and update them accordingly. Just update this to the addresses/midi channels/ports you are using

// hypothetical Channel 1 for Red
if (args[0].value === 1 && args[1].value === 1) {
    receive("/chn1_Red", args[2].value)
}

Cheers,
DMDComposer

1 Like

Awsome! Just did the test for one button and it does work!
Just had to do make a minor correction to the syntax of the CSS

:host {
    background-color: #{'rgb(' + OSC{/chn2_Red, 0} + ',' + OSC{/chn3_Green, 0} + ',' + OSC{/chn4_Blue, 0} + ')'};
}

and adapted to the other channels and it worked!
Thank you so much @DMDComposer
On my way to explore this further!

1 Like

Sorry to bother again.. I'm trying to be specific about where to direct the rgb values, accordingly to the note that's being sent.
For example note 12 on channel 1,2,3 would affect button_1
note 13 on the same channels would affect button_2...
etc
I'm going about filtering in the custom module, and got that working, but I'm failing to associate with the buttons. This is the current custom module

module.exports = {
    oscInFilter: function(data) {
        var { address, args, host, port } = data;

        if (host === 'midi' && address === '/note') {
            var channel = args[0].value;
            var note = args[1].value;
            var velocity = args[2].value;

            
            if ((channel === 1 || channel === 2 || channel === 3) && (note >= 12 && note <= 19)) {
                console.log("Filtered MIDI Note:", args);

                let buttonId = 'button_' + (note - 23);
                console.log("Sending to:", buttonId);

                
                if (channel === 1) {
                    console.log("Channel 1, Sending Red Value:", velocity);
                    receive("/chn2_Red", velocity);
                    receive('/' + buttonId + '/chn2_Red', velocity);  
                }
                if (channel === 2) {
                    console.log("Channel 2, Sending Green Value:", velocity);
                    receive("/chn3_Green", velocity);
                    receive('/' + buttonId + '/chn3_Green', velocity);  
                }
                if (channel === 3) {
                    console.log("Channel 3, Sending Blue Value:", velocity);
                    receive("/chn4_Blue", velocity);
                    receive('/' + buttonId + '/chn4_Blue', velocity);  
                }
            }
        }

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

It's generating and sending to the correct button_id, but I think it's the CSS part that I'm failing.

Got it working! It's completely solved.

1 Like

hi,

maybe post the solution to help someone someday
cheers

Sure, it is almost everything that I already had posted. Just needed to initiate the color values.

let colors = {
   note number: { red: 0, green: 0, blue: 0 }, //replace note number with the note(s) you want to serve as trigger
    
};

module.exports = {
    oscInFilter: function(data) {
        var { address, args, host, port } = data;

        if (host === 'midi' && address === '/note') {
            var channel = args[0].value;
            var note = args[1].value;
            var velocity = args[2].value;

            if (colors.hasOwnProperty(note) && (channel === 1 || channel === 2 || channel === 3)) {
                console.log("Filtered MIDI Note:", args);

                if (channel === 1) colors[note].red = velocity;
                if (channel === 2) colors[note].green = velocity;
                if (channel === 3) colors[note].blue = velocity;

                var rgb = 'rgb(' + colors[note].red + ',' + colors[note].green + ',' + colors[note].blue + ')';
                receive(`/button_${note}/color`, rgb);
            }
        }

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

the css will be
:host {
background-color: OSC{/button_x/color}; // replace x with the actual button number
}

Hope it helps anyone!
Cheers!

3 Likes