Building a TouchOSC/MIDI Remote template

@Mikey_Mike If you want to get the track name in Open Stage Control, yes, I did it here :

For the rest, in open stage control you just have to create fader/button/knob widget with the preArgs you want and target them in the cubase midi remote.

1 Like

Can you help me out here.
Since the MIDI-Setup has changed in Cubase 11/12 I don’t know how to include my TouchOSC.
Do I have to create a new MIDI-Device and bind it to the TouchOSC-bridge?

@HorNet505 sorry for the long silence - you need to build a MIDI Remote, yes, and then bind it to your physical controller.

There’s still some retrocompatibility with the Generic Remote, but as I understand it, soon that’s going away.
To me, this seems like a nice opportunity to learn new tools and add some custom commands - for example, in the old generic remote you couldn’t add pres like Gain, Low Cut and High Cut except as part of your 8 Quick Controls. With the new API you can, especially if you delve into JavaScript.

Does new midi remote can send channel name to touchosc?

@Sergey_Berezutskiy not exactly.
What I did (with some help from people in this forum) is converting the channel name to a SysEx containing the ASCII numbers of each character.
On the TouchOSC side, there is an OnReceiveMIDI() function that takes that SysEx message and retranslated it into a string.

1 Like

is it possible with Touch OSC mk1, make something similiar as motorized fader ?
if i select new channel, fader in touch osc automaticaly set values from Cubase selected channel

@Sergey_Berezutskiy Again, yes.
You need to have TouchOSC bridge both sending and receiving.
If you’re planning to use an old tablet, keep in mind that cabled connection works faster than wi-fi, and, mainly, do not expect anything realtime because even tethered connection in my case yielded very poor results.

Also I suspect a wacko like myself could make names come up even in TouchOSC mkI, it’s a hell of a hack but I’d do it this way:

  • Limit the total length of a name to 16 characters
  • Use a monospaced font
  • Limit characters to a selec…

… no this is going to be too much trouble and fun. I’m going to do it myself. If I want to. When I have time. If I don’t have any Star Trek rewatches going on.

But it’s doable.

1 Like

@m.c

Quick update - I totally used and implemented the controlValue addition that you made to the code.
For every QCnn (QuickControl number), a new SysEx message is passed on to TouchOSC as well.
Thanks for that - now if a QC is MIDI it shows [0…127], if it’s Audio it’s [-oo…6dB], if it’s a switch like a filter slope it actually shows the selected one [-6 / -12 / -24 … -whatever dB/oct]

It works for everything I chuck in (with some limitation - especially with Vienna Ensemble instances).

Thanks a lot for that. I find it especially useful using in together with a small, old Novation LaunchControl which, in itself, doesn’t have any screens, so it’s very difficult to be precise.

As always - since I’m using a 10 year old (and counting) tablet - this is not meant for realtime, but it’s a nice tool to have.

Great, good to know!

Why? Is it lagging?

@m.c Yes it is, but it’s not Nuendo’s fault.

TouchOSC works with a little helper program called TouchOSC Bridge based on Bome MIDI, which acts as, well, a bridge between MIDI broadcast over Wi-Fi and the PC… and back.

The other supported method is MIDI-over-LAN, with slightly better results. I guess all the latency depends from that. It’s not a dedicated device, after all, and God knows what happens on the network side of things. Heck, it could even be a firewall thing, and every time I sent stuff over the firewall suspects it’s an intrusion…

Sure, this could be a reason. I’m asking because sending some bytes (sysex) over anything is a pretty instant process. For example on one of my controllers I’m sending around 1kb of combined sysexes every some ms when needed, no lagging.

@m.c

My bottlenecks are mainly due to my fixation with, erm… upcycling, I guess?

I’m running TouchOSC on a Galaxy Tab that is not supposed to have access to updates after Android 4.2 - I’m running SlimROM 7 on it because the new TouchOSC doesn’t run on Android <= 5.0 and it’s got too many cool things not to use it. I think this is the main culprit, really, because as I said, if I bypass the router and connect the tablet via USB, it doesn’t gain much.

1 Like

WiFi can add some delays in transmission for sure.

Also some processes can generate small delays both in cubendo and touchOsc.

For example, touchOsc doesn’t natively support sysex receiving or nrpn. You have to script them to retreive the data, then find a way to transmit it to the receiving ‘control’ via osc loopback or internal messaging.

This can add a few tens of ms. Even if, like me, you use a wired connection.

Hey @thomas_martin, thanks for chipping in.
Unfortunately the issue persists even if I only use a simple fader with MIDI, that is why I feel it has more to do with old hardware.
I noticed that on my phone (where I built a TouchOSC template to control pan via its onboard gyro and accelerometer) the response is better, even if the script is more complex… Just because the hardware is like 10 years newer.

Fabio, would you mind sharing your scripts from your TouchOSC project so I can steal this code? I’m not a programmer but I got your my template working by lifting your incredible resources! This is the last version I have:

function onReceiveMIDI(message, connections)
      
      local ascii = ""    -- For strings in SysEx messages, passed via MRS
      local header = ""   -- Header identifies the type of SysEx message
      local a, r, g, b    -- RGB Colors, passed via MRS
      
      --------------------------------------------------------------------------------
      -- SYSEX CHECK: checks if a received MIDI message is a SysEx message by looking
      --              at the first and last bytes, then checks length.
      --------------------------------------------------------------------------------
            
        if ((message[1] == 0xF0) and (message[table.maxn(message)] == 0xF7)) then

          if (table.maxn(message) < 7) then
            do return end  
          end
          
          for i = 2, 5 do
            current_char = string.char(message[i])
            header=header..current_char
          end
          
      --------------------------------------------------------------------------------
         
          -- ┌────────────────────┐
          -- │ SYSEX HEADER CHECK │
          -- └────────────────────┘
          
          if header == "NAME" then        
          
            for i = 6, (table.maxn(message)-1) do
              current_char = string.char(message[i])
              ascii=ascii..current_char
            end
            print(ascii)         
                   
            root.children.SelectedTrackName.values.text = ascii
            
            elseif header == "FQC1" then        
          
            for i = 6, (table.maxn(message)-1) do
              current_char = string.char(message[i])
              ascii=ascii..current_char
            end
            print(ascii)         
                   
            root.children.FQC1.values.text = ascii
          
          elseif header == "COLR" then
            
            for i = 6, (table.maxn(message)-1) do
              current_char = string.char(message[i])
              ascii=ascii..current_char
            end
                        
      
            r=message[6]/256
            g=message[7]/256
            b=message[8]/256
            
          
            -- Change color without affecting the alpha channel

            root.children.SelectedTrackName.color.r = r
            root.children.SelectedTrackName.color.g = g
            root.children.SelectedTrackName.color.b = b
                      
          else           
            print("Unrecognized SysEx Message")
            
          end
               
        end
   
end

So now I just need that LUA statement for the blank QC’s and the sysex code for interpreting the QCs to text in TouchOSC. You’re making my template dreams come true! Thanks so much. I certainly wouldn’t be mad if you shared the whole thing so I can learn from it but I leave that as your call.

1 Like

Hey @varesejr,
I was surely planning to do that but never committed to it because I always feel like there’s so much more I could do!
Bit I’m fast realising that people here might contribute a lot more to it. I barely updated it since I got my most used functions working.
I’ll upload tomorrow :wink:

1 Like

Hi everyone,
so I’m sending you my entire project, complete with Midi Remote, PLEs and the TouchOSC template I’m using.
I put the QC faders as interactive already for you, some of you might like that.
Curious to see what people will build on it. I saw that on VI-Control somebody adapted the script already for Open Stage Control…

There’s a few readme files that I just quickly wrote, just for you to have a look at what goes where.

HexFM_NAVI_v2.zip (90.6 KB)

Edit:
Of course there are a few known bugs, so I’m offering this “as is”, but if there’s really something I ought to fix, let me know.

Edit of edit:
Oh my God I almost forgot. NAVI wouldn’t even been possible without the help and patience of @Jochen_Trappe (who pointed me in the right direction) and @m.c (who rectified some of my “monkey with a keyboard” approach with much more sense), and some of the good people and resources on the unofficial TouchOSC Discord (of which I cannot find a link 'cause I’m a dinosaur).

3 Likes

@varesejr oh I saw what you did there with the “FQC1” value instead.

What I did instead is checking if a SysEx starts with “QC0” (because they’re QC01, QC02 … QC08) and then find every group in the TouchOSC controls that has name QC0x. This way if you have more than 1 group called “QC01”, they all get the update.
Another system I used is the Tag field, but for name and color change.

There are two occasions where a recursive function is used: one is to look up multiple elements like QC01 QC02 or QV01 QV02 (for the values), one is if I want to broadcast the color change or name to children of children of children (I tagged every box or fader that I want to change name&colour with a “Delegate_NC” tag)

Hope you’ll find my LUA script clear enough but if you’ve got questions drop me a line here or via email (it’s in a readme file in the package).

Brilliant stuff! You’re a legend for solving all this. It’s such a shame Cubase doesn’t support OSC cause this could have been a cakewalk not having to solve all the SYSEX text nightmare. I see that your template is set up to work with Track Quick controls…How would I change the following code to pull Focus Quick Control labels and values instead? I’m sorry if this is a dumb question but I am having trouble making sense of the midiremote api.

var QCName = {}



/**
 * @param {MR_ActiveDevice} activeDevice
 * @param {string} QCnum
 * @param {string} QCreference
 * @param {string} title
 */

function SysExQCLabel (activeDevice, QCnum, QCreference, title) {

    
    if (QCreference != '')
        {
            // if (QCreference == hostSelectedTrackInstrumentName || QCreference == hostSelectedTrackName) {title = QCreference + " - " + title}
           

            var msg = [0xF0, 0x51, 0x43, 0x30, QCnum.charCodeAt(0)];
            // console.log(QCnum.charCodeAt(0).toString())
            for (var i = 0, len = title.length; i < len; ++i) {msg.push(title.charCodeAt(i)) }
            msg.push(0xF7)
            
            midiOutput.sendMidi(activeDevice, msg)


            console.log('Sending QC0' + QCnum + ": "  /* + msg.toString() + " | " */  /*+ QCreference + " - " */ + title)

    }

}


function SysExQVLabel (activeDevice, QCnum, value, arg3) {


    
    if (value != '')
        {
            // if (QCreference == hostSelectedTrackInstrumentName || QCreference == hostSelectedTrackName) {title = QCreference + " - " + title}
           

            var msg = [0xF0, 0x51, 0x56, 0x30, QCnum.charCodeAt(0)];
            // console.log(QCnum.charCodeAt(0).toString())
            for (var i = 0, len = value.length; i < len; ++i) {msg.push(value.charCodeAt(i)) }
            msg.push(0xF7)
            
            midiOutput.sendMidi(activeDevice, msg)


            console.log('Sending QV0' + QCnum + ": "  + " | Value: " + value + " | MSG: " + msg)

    }

}

@varesejr yeah, sorry, using big orchestral templates for game music so I’m a track QC person…
I’ll have to open the script, I didn’t modify it in… Uh, four months, I guess?
I can open it tomorrow and have a look but probably someone else here might chip in too.

1 Like