Is it possible to rechannelize MIDI Note On Data?

blyons

2013-05-15 00:49:04

Hi all,

I have a MIDI controller keyboard that I'd like to use the bottom octave for to rechannelize all outogoing data as follows:

1. Hit lowest key in bottom octave: All note on/note off above the first octave are sent out at channel 1.
2. Hit second lowest key in bottom octave: All note on/note off above the first octave are sent out at channel 2.

I know how to capture INCOMING note on message 90 g1 yy.
But, it doesn't look like it's possible to then use g1 in subsequent messages to pass outoing MIDI out to a variable channel:
OUTGOING: 9g1 xx yy.

Is this possible or should I try and rechannelize incoming MIDI Note On/Note Off a different way.

Thanks.

blyons

2013-05-20 03:15:09

...the easiest way I've thought to accomplish what I'm trying to do using Bome MIDI translator is to trap a note on in the lower octave and store it to a global variable. Note on/offs that occur above the bottom octave will be sent out the appropriate channel based on the value of the global variable. I'll need 16 If then else blocks to accomplish this, but this is the easiest way that I can think of to get this done with MT. If I had the ability to use the global variable directly in the message, i might be able to save all of the IF/THEN coding. i.e. If global variable is set to channel 10 (Hex A) and a note on occurs above the bottom octave, then rechannelize the note on to channel 10 (A) . 80 50 7F would be translated into 8A 50 75. The IF/THEN will accomplish the same thing, I just have to write more rule code.

metastatik

2013-05-20 05:58:21

If the input is always coming in on channel 1, then this would be an easy way of doing it:

Code: Select all

Incoming Message: pp qq vv
Rules:
if pp < 128 then exit rules, skip Outgoing Action
if pp > 144 then exit rules, skip Outgoing Action
if qq < 12 then goto “Set Channel”
rr=pp+ga
exit rules, execute Outgoing Action
Label “Set Channel”
if pp != 144 then exit rules, skip Outgoing Action
ga=qq
exit rules, skip Outgoing Action
Outgoing Message: rr qq vv
The first two rules ensure that we’re dealing with a note message. If the controller only sends note messages, these rules are unnecessary.

The third rule jumps to the Set Channel label if we’re dealing with the lowest octave. Otherwise, the fourth rule adds the channel offset (ga) to the status byte to set the channel. And the fifth rule sends out the rechannelized note message.

The Set Channel label first checks that we’re dealing with a note on (no need to set the channel on note on and note off). Then it stores the channel offset, which is equal to the incoming note number (qq), and exits.

This is a bit unsafe though because it can allow for hung notes if you’re holding down a note while changing the channel. You can prevent that by employing a counter (gb) like so:

Code: Select all

if pp < 128 then exit rules, skip Outgoing Action
if pp > 144 then exit rules, skip Outgoing Action
if qq < 12 then goto “Set Channel”
rr=pp+ga
if pp==144 then gb=gb+1
if pp==128 then gb=gb-1
exit rules, execute Outgoing Action
Label “Set Channel”
if pp != 144 then exit rules, skip Outgoing Action
if gb > 0 then exit rules, skip Outgoing Action
ga=qq
exit rules, skip Outgoing Action

glennyg

2014-03-06 16:25:52

I made this one which avoids hung notes by always passing note off or note-on-velocity=0 messages through. Hope you find it useful. You can change channels at any time, even while holding notes, and you won't get any hangs.

Note that this one does channel layering, not just switching. So you can have Ch1 or Ch2, Ch1 AND Ch2, or nothing. Duplicate the translator and adjust the offsets and global variable targets and you can switch between, combine in any way, mute and unmute all 16 channels without hung notes.

UPDATE! This is several lines shorter and doesn't use any Labels. Also previous version allowed sustain pedal to cause hung notes.

Controller is transmitting on Ch1. Switches assigned to CC102, CC103, CC104 etc.

Check for CC message > check if matches the controller switch > set global variable value.
Check for sustain=off message, always send it.
If controller is sending note-on-velocity=0 instead of note off, make it a note off message (saves polyphony) and always send it.
Check for note off message > always send it.
If flag shows switch is off, don't transmit any other message types (i.e. transmits note off and sustain off messages only).
----------
Translator 1
(for control of Ch1)

Incoming Message: pp qq vv

Rules:
if pp==176 then oo=pp+qq
if oo==278 then oo=oo+vv
if oo==278 then ga=1
if oo==405 then ga=2
if oo==240 then oo=oo+vv
if oo==240 then exit rules, execute Outgoing Action
if pp==144 then ww=pp+vv
if ww==pp then pp=pp-16
if pp<144 then exit rules, execute Outgoing Action
if ga==1 then exit rules, skip Outgoing Action
exit rules, execute Outgoing Action

Outgoing Message: pp qq vv
-----------
Translator 2
(For control of Ch2. Note the offsets from Translator 1. Apply on duplicate Translators for up to 16 channels)

Incoming Message: pp qq vv

Rules:
pp=pp+1
if pp==177 then oo=pp+qq
if oo==280 then oo=oo+vv
if oo==280 then gb=1
if oo==407 then gb=2
if oo==241 then oo=oo+vv
if oo==241 then exit rules, execute Outgoing Action
if pp==145 then ww=pp+vv
if ww==pp then pp=pp-16
if pp<144 then exit rules, execute Outgoing Action
if gb==1 then exit rules, skip Outgoing Action
exit rules, execute Outgoing Action

Outgoing Message: pp qq vv
----------

blyons

2014-03-06 16:42:06

Thanks glenn,

I'll give it a shot!

Bill

glennyg

2014-03-06 17:37:32

I've refined it further soon after posting. Copy it again to be sure you have the updated code.

glennyg

2014-03-07 09:53:38

Refined again to handle controllers that send note on with velocity=0 instead of proper note off messages. Replacing those with note offs saves polyphony.

glennyg

2014-03-07 10:57:51

Edited again. Now doesn't reset controllers if the switch is off. So you could be playing an instrument, apply ModWheel, turn the channel off and when you come back to it and turn the channel back on the ModWheel will still be at the value you left it.

I've replaced the code with the improved code in the post above.

cheers
g

glennyg

2014-03-07 15:33:37

More economical version now above. Also fixed a problem with sustain messages causing hung notes.