Bidirectional Fader

Hello,

Is bidirectional midi faders possible?

I am trying to update the midi faders in OSC when they receive a midi message from Cubase.
I have managed to setup Cubase to send the appropriate midi cc messages. And, can see that OSC in receiving them when I debug. But, the faders will not move from the incoming feedback.
What am I doing wrong, is this possible to achieve this?

Here is the incoming midi message from Cubase into OSC:
(DEBUG, MIDI) in: CONTROL_CHANGE: Channel=1, cc=13, value=95 From midi:Omnisphere

Also, is it a good idea to have this send and receive on the same midi connection. Or should I create two separate midi connections, as (1) IN, (2) OUT ?

Check this paragraph. The fader needs to match the preArgs ([1, 13] in this case) and its target must contain "midi:Omnisphere", as is or in an array:
["midi:Omnisphere", "midi:SomeOtherPort"]
)

Here is screenshot of the fader setup. I think I have it setup as you described. Am I missing something?
bidirectional fader

Thank you for your reply and the help!

The fader's config looks ok, are you using a custom module that might discard the incoming message ?

Yes, I am using a custom module. I don't fully understand how to use it, and have been trying to apply it to Tab switching. You see my discussion about it here:

Here is the custom module I'm currently using:

module.exports = {

    oscInFilter:function(data)
	{
        var {address, args, host, port} = data

        if (address !== '/control') return
		if (args[1].value < 117) return
		if (args[1].value == 127) 
			{
			send('midi', 'OSCtoCUBASE', '/control', 1,126,1)
			return
			}	
	return {address, args, host, port}
	},
}

Whenever you're using return with nothing after in your custom module, you're preventing the original message from reaching the clients/widgets. Your custom module doesn't let anything pass (almost every possible case ends with a return, the last return statement (return {address, args, host, port}) is almost never reached (the only messages that pass are cc between 118 and 126). If you just want to send a message when receiving a specific control change you could write it in a way that doesn't discard all messages:

if (address === '/control' && args[1].value == 127) {
    send('midi', 'OSCtoCUBASE', '/control', 1,126,1)
    return
    // the original message will be discarded in this case
}

// if no other return statement is reached, let the original message pass
return {address, args, host, port}

Thank you!! This works perfectly. I now have feedback on my OSC faders!
Here is the edited custom module:

module.exports = {

    oscInFilter:function(data)
	{
        var {address, args, host, port} = data
		if (address === '/control' && args[1].value == 127) {
			send('midi', 'OSCtoCUBASE', '/control', 1,126,1)
			return
		}
	return {address, args, host, port}
	},
}

The reason for creating the Custom Module is to achieve Tab Switching, when OSC receives a specific midi message from Cubase.

OSC receives the cc127 from Cubase, the custom module ignores this and sends back cc126 to Cubase.

When Cubase receives this cc126 on a selected track, I have placed a Midi Transformer insert that transforms the incoming cc126 from OSC to selected values (cc117-125, with values set to 0-127) and then sends these specific values back to OSC.

I can see the correct incoming midi CC reaching OSC when I debug.

My question now is how do I achieve the Tab Switching from the incoming midi CC information?
For example:
if receive args:[1,117,1] then select Tab_01
if receive args:[1,117,2] then select Tab_02

Selecting a tab can be done either by setting the value of its parent container (0 = first tab selected, 1 = second tab selected, etc), or with the /TABS command:

if (address === '/control' && args[1].value == 117) {
    if (args[2].value === 1) {
        receive('/tab_parent_address', 0) // 0 = first tab
    } else if (args[2].value === 2) {
        receive('/TABS', 'tab_2_id')
    }
    return // bypass  cc 117
}
1 Like

Thank you jean-emmanuel for your continues help and guidance! I greatly appreciate your time.

Do I add the /TABS command to my existing custom module? If yes, is there a correct procedure to follow for adding these additional statements?

With a little experimentation I created this version of the Custom Module. It seems to be working for me. Is this the correct way to do it?

Also, is there a way of including a default tab, when no midi message is received?
I would like to have a blank Tab, so when I choose other locations within Cubase, like a folder, the Tab panel will default to the blank Tab.

Here is the updated custom module:

module.exports = {

    oscInFilter:function(data)
	{
        var {address, args, host, port} = data
		if (address === '/control' && args[1].value == 127) {
			send('midi', 'OSCtoCUBASE', '/control', 1,126,1)
			return
		}
		if (address === '/control' && args[1].value == 117) {
		if (args[2].value === 1) {
			receive('/panel_articulations', 1) // 0 = first tab
		} else if (args[2].value === 2) {
			receive('/panel_articulations', 2)
		} else if (args[2].value === 3) {
			receive('/panel_articulations', 3)	
		} else if (args[2].value === 4) {
			receive('/panel_articulations', 4)	
		} else if (args[2].value === 5) {
			receive('/panel_articulations', 5)				
    }
		return // bypass  cc 117
}
	return {address, args, host, port}
	},
}