Converting system exclusive to control change

Yes, but it requires some understanding about what bytes of the sysex message are changing and then you can extract those bytes and scale them into a CC message.

Ok, now that I know it’s possible maybe the next thing for me will be to try scripting (for some other things). SysEx on the other hand is not so foreign for me.
Thank you again!

@Brandon I don’t really understand the definition of NRPN versus Sysex. I had thought that because they were exclusive to the device they are categorised as non-recognised. Is this the table you were referring to from the SKPro manual?

NRPN is just a way to use values that are not officially part of the standard and they use a combination of CC numbers (99 followed by 98) with values to represent some other parameter known to specific devices.

Yes in part that is what I am referencing but there would be a ‘key’ of sorts at the very bottom of the page, this page or one previous where it describes the entire SysEx string becuase what is on this page alone doesn’t give all the info you need.

That being said, this looks nearly identical to the XK-5 apendix but I am certain that the individual parameter data is likely to be different since the SKPro has more internal variables and different control surface inputs. But the fundementals seem to be the same.

My point though, or at least from my own use case, is that if you want surface controls to send and be re-injected as useful to GP messages, those are almost certainly going to be either CC messages or NRPN (groups of three CC messages where one is a constant and two are the variables) messages.

It’s rare on Hammond keyboards that the control surfaces actually send SysEx. I’ve seen this on other keyboards though.

Where I use SysEx on the XK-5 is to create a script whereby I send SysEx from a widget to control something in the sound engine (tube drive) within the XK-5 itself because I use the XK-5 as a sound source.

If you are strictly wanting to use the SKPro as a controller, you likley will not need SysEx messages.

In either case I can likely help.

You need to first build a table of what all your surface controls actually output and to do this I just open Midi Monitor in GP and document what each knob does. Start without displaying SysEx and then if you find a knob that isn’t trasnmitting any messages turn it on and see if it’s sending SysEx.

Here’s the table I built for the XK-5 for the NRPN: Same three CC values for many hardware controls... and Rig Manager - #21 by brandon

Once you have the lay of the land… you can then build a gig script (I can help) that re-injects these clusters of messages into a CC message that you can then map to a widget (I’d first organize these injected messages in rig-manager) and then assign them to parameters in the plugin.

It’s unlikley that this would be all you’d need but B3-X does have an advanced settings section where you can assign the plugin to the profile of a hammond keyboard and I am pretty sure SKPro is one of the options. In practice I have found this only works if you’re using it in stand alone mode and only so well. Assuming you are using GP for more than just this scenario, using a gig script is the way to go.

Also… some parameters, like drawbar sliders, will likley send normal CC messages not NRPN (groups of 3 messages) so be sure to figure out comprehensively what all control surface inputs send.

Lastly, on the XK-5 there are deeper menus that allow for instance the B-natural preset key for the lower manual to be ‘assigned’ so they never function as drawbars but instead send CC mesages. Given that the SKPro doesn’t have 4 sets of drawbars this probably isn’t a feature but do look over if there are internal to the SK controls that would enable features which would change the behavior of outgoing messages just so you are aware.

1 Like

[quote=“brandon, post:45, topic:10479”]
You need to first build a table of what all your surface controls actually output and to do this I just open Midi Monitor in GP and document what each knob does. Start without displaying SysEx and then if you find a knob that isn’t trasnmitting any messages turn it on and see if it’s sending SysEx.
[/quote]

Footnote… this will not work if you are already using a script which reinjects sysex or nrpn messages so disable any such script first… otherwise all incomming messages that are not CC or note messages will be filtered out.

[quote=“CarlP, post:43, topic:10479”]
I had thought that because they were exclusive to the device they are categorised as non-recognised.
[/quote]

The are non-registered, not non-recognized. Non-registered meaning they are not dedicated to a single CC message that would typically be channel assigned and universally recognised.

Great, thank you @Brandon . This is beginning to make sense. Is the key?

I can make a table of messages received using Midi monitor and come back to you. I know that the Leslie Slow/Fast button does send messages that do not appear to be Sysex, and the same is true for percussion settings.

The drawbars map easily, and the mod wheel maps to the Leslie speed, not that I like using that - just not intuitive.

Appreciate you take the time to help

Hi @Brandon I’ve finally created this Excel to how what messages are sent by the SK Pro when I use different controls. Is this what’s needed to create a midi map?

Hammond SK Pro for GP - Sheet1.pdf (2.5 MB)

@CarlP

Try compiling this pasted script as a Gig Script.

You will need to define your SKPro in Rig Manager as “SKPro” or change the name of it in this script to match what it’s named in the Rig Manager now. It will need to be added to Rig Manager for this to work because this script “injects” the incomming NRPN as CCxxx values as if they are native to the SKPro. Then those parameters can be defined as aliases in Rig Manager and then interchangably assigned to widgets.

I’ll break down one instance here… the first line is just a label because the // states this line is just a comment:

        // Leslie => CC#103

Next is setting the static values of the CC99 and CC98 messages. This is derived from your spreadsheet values. In this case, CC99 is 39 and CC98 is 2:

        CC99 == 39  && CC98 == 2  Do InjectMidiEventViaRigManager(SKPro,

Then this line is specifiying what new CC value this combination is creating, in this case CC 103, and if it’s value range is binary like a switch or a range. This is a switch:

MakeControlChangeMessageEx(103, CC_msg.GetCCValue()*127, 1));

OK, here’s the full script to try and compile once you’ve set up the Rig Manager instance. Let us know what works and what doesn’t.

Var
  SKPro                      : MidiInDeviceAlias // Define SKPro as a RigManager alias to the real controller
  CC_State, CC99, CC98       : Integer = 0;  

On ControlChangeEvent(CC_msg:ControlChangeMessage) Matching 99,98,6 from SKPro
    Select
      CC_State == 0 Do if (CC_msg.GetCCNumber()==99) Then CC99 = CC_msg.GetCCValue(); CC_State = 1 Else CC_State = 0 End
                       
      CC_State == 1 Do if (CC_msg.GetCCNumber()==98) Then CC98 = CC_msg.GetCCValue(); CC_State = 2 Else CC_State = 0 End
    
      CC_State == 2 Do
        if (CC_msg.GetCCNumber()==6)
        then
          Select
			
            // Leslie => CC#103
            CC99 == 39  && CC98 == 2  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(103, CC_msg.GetCCValue()*127, 1));
 
            // Reverb Depth => CC#106
            CC99 == 16  && CC98 == 2 Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(106, CC_msg.GetCCValue(), 1));
						
            // Chorus => CC#108
            CC99 == 39  && CC98 == 5  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(108, CC_msg.GetCCValue()*127, 1));
						
            // Reverb => CC#109
            CC99 == 16  && CC98 == 0  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(109, CC_msg.GetCCValue()*127, 1));
            
            // Percussion Switch => CC#112
            CC99 == 38  && CC98 == 0  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(112, CC_msg.GetCCValue()*127, 1));
            
            // Percussion Volume => CC#113
            CC99 == 38  && CC98 == 3  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(113, CC_msg.GetCCValue()*127, 1));
            
            // Percussion Decay => CC#114
            CC99 == 38  && CC98 == 2  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(114, CC_msg.GetCCValue()*127, 1));
            
            // Percussion Third => CC#115
            CC99 == 38  && CC98 == 1  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(115, CC_msg.GetCCValue()*127, 1));
            
            // Overdrive Switch => CC#116
            CC99 == 41  && CC98 == 0  Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(116, CC_msg.GetCCValue()*127, 1));
            
            // Overdrive Depth => CC#117
            CC99 == 41  && CC98 == 2 Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(117, CC_msg.GetCCValue(), 1));
             
            // Output Level => CC#118
            CC99 == 17  && CC98 == 6 Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(118, CC_msg.GetCCValue(), 1));           
          End  
        end
        CC_State = 0; 
End
End
    On ProgramChangeEvent(m : ProgramChangeMessage) from SKPro
  InjectMidiEventViaRigManager(SKPro, m);
  If m.GetChannel()==2 && m.GetProgramChangeNumber()>=100 && m.GetProgramChangeNumber()<=127
  Then
    InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessage(m.GetProgramChangeNumber(),127));
  End
End
1 Like

Thank you very much! It would have taken me forever to get to that point and may have given up.

Mostly it works as planned. A few anomalies:

  • Chorus switch - doesn’t switch on or off (it’s actually the Upper /Lower assign button on the SKPro - effectively it’s switched off when neither Upper or Lower have Chorus assigned). When I try Midi Learn it doesn’t seem to be sending a message at all

  • Leslie - I have to double click the button on the SKPro to get it to change, and also means the ‘Fast’ light on the SKPro is lit whether the Leslie is running fast or slow

  • As a bonus, the footswitch I sometimes use to change Leslie speed performs in exactly the same way as the Leslie switch - ie it has to be pressed twice to change, and twice to change back again.

  • The Mod wheel works for Overdrive depth, but also still changes the Leslie speed at the same time (the default mapping for the B3X

  • The drawbars still work as they did - also default mapping of the B3X

So this sounds like it might need an array to function since it’s supposed to cycle through 3 or 4 different states. I don’t know how to help you on that to be honest.

I think this has to do with the widget behavior setting. You should be able to adjust this to work.

You are using widgets right?

Is that really a bonus? I use a footswitch to control my leslie too but I don’t have to double click it… so again this should be adjustable with the widget settings.

You are using widgets right?

You’re not using widgets are you?

You need to midi learn the widgets to the device aliases and you need to use widgets and parameter learn the widgets to the things you want to control in B3X. Right now B3X is defaulting to use Mod Wheel values (are you using a preset within B3X?) and your SKPro is still sending normal mod wheel values but it’s also sending the NRPN values too (I assume) and we’re capturing those NRPN and making new CC messages from that… so you’re sending dual messages thru to B3-X from mod wheel. You need to break this assignment of your mod wheel’s midi CC value from reaching B3-X and only let the scripted value (// Overdrive Depth => CC#117) from the mod wheel reach B3-X.

This is good yes? However, I would set up drawbar widgets to control these and midi learn the widgets to the incoming values from the SKPro.

Yes I’m using widgets.

Leslie Fast/Slow now working perfectly - I’d set it to Latching in a previous attempt to get it to work. Footswitch now behaving correctly too (I meant it was a bonus in that it was doing exactly the same as the switch without having to set up separately)

The Mod Wheel seems to be a default setting for the Leslie switch, but I may need to dig around in the SKPro or B3X manuals to work out how to disable that. Unless there’s a way of filtering that action out in GP?

I can live without Chorus on/off switch. Or I can use a switch on another controller for it.

I’ve already mapped the drawbars, and they’re working as expected.

Do I need to do anything to make the Gig Script operate globally, whenever GP is launched?

In Midi Monitor, are you seeing two different CC values when you move the mod wheel? If so what are they?

You can add a midi filter after the input block and before the VST it’s sending to and block the CC value that it’s sending.

Or you can intercept that value by mapping it to a widget that is then not assigned to the plugin at all. You can then hide that widget.

You can try this updated line of code for that and see if that changes the behavior better:

// Chorus => CC#108
CC99 == 39 && CC98 == 5 Do InjectMidiEventViaRigManager(SKPro, MakeControlChangeMessageEx(108, CC_msg.GetCCValue(), 1));

No, the gig script is the top hierarchy of scripting but it is associated with the gig file you are opening, it’s not omni presenet in all of GP… so you need to add it into whatever gig file you are using.