The following should get you close. Since you need translation, your best option for virtual ports is to use Bome MIDI Translator Pro.
You can download a trial copy of Bome MIDI Translator Pro here. It is fully functional but times out every 20 minutes.
Translators in preset 0 are basicall my standard template and not directly related to your requirements.
Translator 1.0 (Preset 1 translator 0) handles the shift function and sets or resets the value of the global variable “ga” depending on the value. It does not send any MIDI output so i acts as a shift key. The incoming trigger is CC120 on MIDI CH1 with any value.
Here are the rules:
// set the value of global variable ga based
// on the incoming value (shift function)
if qq==127 then ga=1
else ga=0
Translator 1.1 will translate the incoming note but only if the shift is on (ga=1). We start with note 40. Incoming is note-on any note on MIDI CH 1 set value to local variable pp. The rules adjust pp in the the local variable tt for the outgoing CC.
Here are the rules:
// if not shifted (ga!=0 then let the
// MIDI router pass through the message
if ga==0 then exit rules, skip Outgoing Action
// Start with note 40
if pp<40 then exit rules, skip Outgoing Action
// Set tt as the offset for the outgoing CC#
tt=pp-39
Well since we are using this as a shift key, we cannot tell whether the next MIDI message will be a note or not so it would be difficult to tell when to suppress and when not to suppress the outgoing MIDI message. If this is required, I suppose we could set a timer and if we don’t get a note message within a given time, we could send it through but there would be a delay based on the value of the timer. Is this what you want?
I used aliases in this example as follows:
You will need to assign them to your desired physical MIDI ports. You will be prompted when opening the project.
You can learn more about aliases from this tutorial.
I set up translator routing at the preset level.
For more information about device selection, see this tutorial.
Anything not handled by a translator is passed through untouched using the Bome MIDI translator Pro MIDI router.
shift-example-2025-12-18.bmtp (3.0 KB)
Steve Caldwell
Bome Customer Care
Also available for paid consulting services: bome@sniz.biz