No internet connection
  1. Home
  2. How to

How to remap a midi controller?

By @Eytan
    2019-01-18 16:39:17.750Z

    Hi,
    If I have a midi controller that doesn't have a control editor, Is it possible to reassign the controls?
    For example: Change the mod wheel from CC1 to CC2.
    Thanks

    Solved in post #2, click to view
    • 23 replies

    There are 23 replies. Estimated reading time: 13 minutes

    1. Hi @Eytan.

      You can create a script in SoundFlow like this:

      
      var processed = false;
      //Check if we're receiving a CC on channel 1:
      if (event.trigger.midiBytes[0] == 0xB0) {
      
          //If we are, check if it's CC1:
          if (event.trigger.midiBytes[1] == 1) {
      
              //We received a CC1 on Channel 1, get it's value:
              var value = event.trigger.midiBytes[2];
      
              //Send out a CC2 on SoundFlow Custom Midi Output 1
              sf.midi.send({
                  midiBytes: [0xB0, 2, value],
                  outputNum: 1
              });
      
              //Mark that we're processing this
              processed = true;
      
          }
      
      }
      
      //If we didn't reroute the message, just pass the incoming message through
      if (!processed) {
          sf.midi.send({
              midiBytes: event.trigger.midiBytes,
              outputNum: 1
          });
      }
      
      

      This script will check if it receives a CC1 on Channel 1. If so, it will redirect it to CC2 on Channel 1. Any other message will be passed through.

      It will send all its output out via the virtual midi port "SoundFlow Custom Midi Output 1".

      To make it work, you need to assign your midi controller as a Midi Device trigger in SoundFlow to this command.
      Then in your DAW, you'll need to use SoundFlow Custom Midi Output 1 as your input instead of the midi controller.

      So your routing would be:

      MIDI Controller -> SoundFlow script (above) -> SoundFlow Custom Midi Output 1 -> DAW.

      ReplySolution
      1. Shorter version of the script:

        
        //Check if we're receiving a CC1 on channel 1:
        if (event.trigger.midiBytes[0] == 0xB0 && event.trigger.midiBytes[1] == 1) {
            //Send out a CC2 on SoundFlow Custom Midi Output 1
            sf.midi.send({
                midiBytes: [0xB0, 2, event.trigger.midiBytes[2]],
                outputNum: 1
            });
        } else {
            //Pass the message through
            sf.midi.send({
                midiBytes: event.trigger.midiBytes,
                outputNum: 1
            });
        }
        
      2. In reply toEytan:

        @Eytan did you get this to work? If not feel free to ask more questions here if you need more steps.

        1. E@Eytan
            2019-01-20 18:56:39.666Z

            Hi, Yes it works perfectly!

            Can you explain me which numbers I need to change in order to rewire the entire thing? Let's say I want to change CC1>>CC101, CC2>>CC102 etc... (you could maybe highlight the places that I need to change in the code?).

            Thanks

            1. This depends a little on how many you'd like to be mapping since we could either just duplicate code or make it a little cleaner to configure for users. How many would you be re-routing?

              1. But to answer your question more directly. Take a look at this script:

                //Check if we're receiving a CC1 on channel 1:
                if (event.trigger.midiBytes[0] == 0xB0 && event.trigger.midiBytes[1] == 1) {
                    //Send out a CC2 on SoundFlow Custom Midi Output 1
                    sf.midi.send({
                        midiBytes: [0xB0, 2, event.trigger.midiBytes[2]],
                        outputNum: 1
                    });
                } else {
                    //Pass the message through
                    sf.midi.send({
                        midiBytes: event.trigger.midiBytes,
                        outputNum: 1
                    });
                }
                

                In the first if line, the == 1 is the CC1, and in the following [0xB0, 2, ...] the 2 is the CC2 that it is being directed to.

                If you want to do CC1 -> CC101 and CC2 -> CC102 you'll need to have another if/else section, as such:

                //Check if we're receiving a CC1 on channel 1:
                if (event.trigger.midiBytes[0] == 0xB0 && event.trigger.midiBytes[1] == 1) {
                    //We received a CC1 (== 1) on channel 1 (0xB0)
                    //Send out a CC101 on SoundFlow Custom Midi Output 1
                    sf.midi.send({
                        midiBytes: [0xB0, 101, event.trigger.midiBytes[2]],
                        outputNum: 1
                    });
                } else if (event.trigger.midiBytes[0] == 0xB0 && event.trigger.midiBytes[1] == 2) {
                    //We received a CC2 (== 2) on channel 1 (0xB0)
                    //Send out a CC102 on SoundFlow Custom Midi Output 1
                    sf.midi.send({
                        midiBytes: [0xB0, 102, event.trigger.midiBytes[2]],
                        outputNum: 1
                    });
                } else {
                    //Pass the message through
                    sf.midi.send({
                        midiBytes: event.trigger.midiBytes,
                        outputNum: 1
                    });
                }
                
                1. Here's a solution that's a little simpler to add new CC's to. This will re-route CC1 to CC101, CC2 to CC102, CC3 to CC103 and CC4 to CC104.

                  var ccRoute = {
                      1: 101,
                      2: 102,
                      3: 103,
                      4: 104,
                  }
                  
                  var route = ccRoute[event.trigger.midiBytes[1]];
                  if (event.trigger.midiBytes[0] == 0xB0 && route) {
                      //Send a re-routed message
                      sf.midi.send({
                          midiBytes: [0xB0, route, event.trigger.midiBytes[2]],
                          outputNum: 1
                      });
                  } else {
                      //Pass the message through
                      sf.midi.send({
                          midiBytes: event.trigger.midiBytes,
                          outputNum: 1
                      });
                  }
                  
                  1. E@Eytan
                      2019-01-21 15:50:27.467Z

                      Well... This is perfect! I'm speechless.
                      Thank you so much:)
                      Eytan

                      1. Happy to hear it :)

                        1. E@Eytan
                            2019-01-22 18:32:45.832Z

                            Hi,
                            I don't know what happened, but I started experiencing an issue with this command every time I use retrospective midi record. Check out this video please:
                            http://www.youtube.com/watch?v=AT4y_GGO_aw
                            It worked properly yesterday and then it started doing that... I tried to copy the script again but nothing changed since it started.

                            1. Hi @Eytan.
                              This is because I made a mistake in the script. We need to pass on the timestamp like this to support retrospective record because it relies on the timestamp to know when an event occured.

                              var ccRoute = {
                                  1: 101,
                                  2: 102,
                                  3: 103,
                                  4: 104,
                              }
                              
                              //Check if we're receiving a CC1 on channel 1:
                              var route = ccRoute[event.trigger.midiBytes[1]];
                              if (event.trigger.midiBytes[0] == 0xB0 && route) {
                                  //Send a re-routed message
                                  sf.midi.send({
                                      midiBytes: [0xB0, route, event.trigger.midiBytes[2]],
                                      outputNum: 1,
                                      timestamp: event.trigger.timestamp,
                                  });
                              } else {
                                  //Pass the message through
                                  sf.midi.send({
                                      midiBytes: event.trigger.midiBytes,
                                      outputNum: 1,
                                      timestamp: event.trigger.timestamp,
                                  });
                              }
                              
                              1. E@Eytan
                                  2019-01-23 08:51:49.864Z

                                  Hi,
                                  Sorry but nothing has changed.

                                  1. E@Eytan
                                      2019-01-24 15:18:18.243Z

                                      Hi, did you get my message?

                                      1. Hi @Eytan.
                                        Thanks for checking. I've been on Sundance so have not been able to double check this. As mentioned in a PM I suspect this is a SF bug. Just to make sure, which SF version are you on? And which Cubase version?

                                        1. E@Eytan
                                            2019-01-30 08:05:45.664Z

                                            SF: Version 2.2.0-preview.1.3 (2.2.0-preview.1.3)
                                            I don't use Cubase. I use Nuendo 8.3.15

                                            1. Thanks! I'll check with Cubase which is what we have here. This will help us narrow down if this is a regression (something that used to work but we messed it up) or if it's specific incompatibility with Nuendo for some reason.

                                              1. E@Eytan
                                                  2019-01-30 17:17:40.783Z

                                                  Awesome. Waiting for an update! Thanks

                                                  1. @JesperA now that you have Nuendo, you might be able to help us test this. I know you're using MIDI rerouting in SF, so maybe you're also seeing @Eytan's problem, maybe you're not. Hopefully that can help us narrow down the issue he was seeing.

                                                    1. So I've never used the timestamps, and retrospect always worked for me (both Cubase 10 and Nuendo 10).
                                                      I'll try to add timestamps to some of my scripts to see if it changes anything.

                                                      What's your Retrospective Record Buffer Size set to?
                                                      Mine is 10000 events. Maybe it's been too low?

                      2. S
                        In reply toEytan:
                        Steve @stevef
                          2021-06-02 15:49:07.069Z

                          Hi @chrscheuer. I have just come across this post as I am considering getting Bome MIDI translator to customise some things on my X-Touch One, but before I do that, I wanted to check whether I could do things with SF instead. Certainly this post shows how to convert one CC to antoher which is very useful, but I wanted to know how far I could go with it.

                          Certainly I notice when settingup a quick macro and converting to a script, that the outputting of MIDI seems easier to script now, eg:

                          sf.midi.sendCC({ outputNum: 1, midiCC: 89, value: 127, });

                          But, can you also do things like checking the value of the incoming MIDI and send based on that? For example, there is a Jog wheel, which I am never going to use for Jog, but want to use it for event volume. The issue is, it sends CC60 wherether turning left or right, but Left is a value of 1 and right a value of 65. So I would want to assign the 65 value to one CC and the other to another CC. Is that possible?

                          Thanks.

                          Steve.

                          1. Hi Steve,

                            @JesperA is currently developing an app for this - you guys might want to talk :)

                            1. In reply tostevef:

                              Hi Steve.
                              As Christian said, I'm working on a super awesome midi remapper. It's very promising.
                              Even though it's already working really well I need to rescript some things to make it better.
                              I'll write you when there's a beta version ready.

                              But it's also fairly easy to remap simple things yourself for sure :)
                              Try creating a script with log(event.trigger.midiBytes) and attach a MIDI device. That gives you the incoming MIDI Message.

                              1. SSteve @stevef
                                  2021-06-02 23:55:22.494Z

                                  Excellent! I look forward to giving it a try, I decided to get Bome Translator for now anyway, and it works really well. I even figured out how to light certain buttons up at certain time using the WK-Audio ID controller in Nuendo as it sends out lots of useful info that nothing else seems to do.