Ignore Certain Note Offs?

I’ve been pulling my hair out for a few days trying to write rules that ignore certain note offs. I can’t figure out how to do this.

What I want to do is split the 88-key range of my MIDI controller into two 44-key zones that control almost the same exact range of notes. This way I can play with octave displacement but the listener will hear a melody confined to a narrower note range which is easier to follow than the disjunct melody created when one uses octave displacement normally.

The problem is that when you assign multiple keys to a single MIDI note the behavior when using those duplicate keys simultaneously is such that holding one key down then proceeding to press and release its duplicate key cuts off the first key held. The desired alternative would be that the first key held down sustains through any releases or note-offs of the same note sent by duplicate keys.

The two solutions in order of desirability that I’ve thought of would be:

  • Only the correct note-offs get through.
  • Notes retrigger when receiving a duplicate note. Meaning when a duplicate note is received, the note being held is sent a note-off and the new note-on passes through as well. This would probably create gaps in MIDI data and is not really desirable.

This is something that I’ve just dealt with by using an instrument rack with instruments set to different keyzones but that makes for suboptimal recorded MIDI data that is spread across multiple octaves and having to use instruments with their transpositions cranked up or down.

Could someone please help with combatting this? Is it possible? Is Bome MTP even the right tool to use to achieve this goal?

So we probably need to track 88 incoming notes in a bitmap (3 global variables). Then use a MOD (%) operator to only send note-off if both notes in the bitmap are off.

If I understand, the idea is to only send a note-off if the corresponding outgoing note in the both note ranges are in a released state. Like say note 24 and note 36 (3 octaves apart). If note 24 is down and 36 is up, then do not send note-off 36. If 36 is down and 24 is up, then do not send note-off 36. However when both are released, send the note-off 36.

This can be done in MT Pro but before I illustrate further, I want to ensure I am documenting the desired behaviour.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Is this what you want to achieve?

I thought it would require a lot more variables but if you can store the data with three global variables that’s wonderful.
The path I was going down was attempting to store 8 or 16 or however many voices of held notes were needed and comparing incoming note-ons and offs somehow to the storage of held notes to determine whether a note-off would be filtered. For the life of me I could not get the variable I assigned to confirm matched notes to track in a usable way. I couldn’t make it like… pitch dependent. Only # of held notes dependent.

Yes. If my brain and comprehension of how you’ve understood me aren’t failing me this is exactly what I want to have happen. For some reason I get confused when you use the exact note values 24 and 36 but I’m pretty sure I would be able to tune the transposition flexibly once I understand the path you lead me down should you decide to help me further.

Maybe a better route to be certain I’ve gotten the desired behavior across is to explain a similar scenario that requires the same functioning…
What if I wanted to use two separate keyboards on different channels and have them behave on one track as if I had them on separate tracks in the DAW? One sends note 36 on channel 1, and the other sends note 36 on channel two. Just as you described with your note values, can two 36’s not conflict with each other and act almost as if another voice was given to the duplicate note by monitoring the released state of notes in a ‘bitmap’? Except for the doubling effect. I understand that two ‘on’'s can occur on the same note but only a single note off for a given pitch value. (Mimicing the behavior of each keyboard having its own separate DAW track by means of filtering note-offs)

I sincerely apologize if thats a different behavior but I’m pretty sure both scenarios require the same MIDI translations and I think I have solidified my point. Hopefully.

OK, you can give this a try but I haven’t full tested it.

I keep a bitmap of all notes in global variables g0-g3. If the bit is one, the note is on if a bit is 0 the note is off. The preset “Set Note State” controls the bitmap.

The preset “Play Notes” is as follows.

For note-on we take the note number and do a MOD 64 to get only the lower 64 notes on the keyboard and then we add an offset ga (which I set to 36) to determine the note played. If you play an upper note (greater than 64) it will drop it into the lower have and then add 36 so the same note is played whether on upper or lower (but the bitmap does not change). We always send the note-on

For note-off, we look at the bitmap and if there is an existing note-on bit set in either the upper or lower portion of the bitmap, then we suppress the note-off. If both the upper and lower bitmap is off then we send the note-off. We again do a MOD 64 and then add ga (36) to send the proper note-off.

I use the global variable zz to determine if I display log messages. (zz=1 means display them)

Here is a log of sending note 1 on followed by note 65 on then note 1 off and note 65 off. Again I offset the output note by 36 which can be changed by changing the value of ga in the Init Preset, Initialize global variables and then restarting the project.

1: MIDI IN [Bome MIDI Translator 1 Virtual In]: 90 01 7F
2: MIDI OUT [Bome MIDI Translator 1 Virtual Out]: 90 25 7F
3: MIDI IN [Bome MIDI Translator 1 Virtual In]: 90 41 7F
4: MIDI OUT [Bome MIDI Translator 1 Virtual Out]: 90 25 7F
5: MIDI IN [Bome MIDI Translator 1 Virtual In]: 80 01 7F
6: 2.1:12 Log global variable = g0
7: 2.1:25 Log lower bitmap state = 0
8: 2.1:38 Log upper bitmap state = 1
9: 2.1:42 Log Supress Note off = 1
10: 2.1:46 Log Note-Off Supressed
11: MIDI IN [Bome MIDI Translator 1 Virtual In]: 80 41 7F
12: 2.1:12 Log global variable = g2
13: 2.1:25 Log lower bitmap state = 0
14: 2.1:38 Log upper bitmap state = 0
15: 2.1:42 Log Supress Note off = 0
16: MIDI OUT [Bome MIDI Translator 1 Virtual Out]: 80 25 7F

Give it a try.

Suppress-Split-Note-Off-2022-09-05.bmtp (5.1 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Haha I’m so glad you came through and delivered this project file! As far as I’ve tested it (with two conflicting keys), it suppresses the correct note-off messages by monitoring the state of each keyzone I think.

It uses things I don’t know how to yet like shifting bits, as well as AND, OR, and XOR operations if I’m not mistaken.
I’m just having a little bit of trouble changing the split of the keys. As it is now the low C key plays the same note as a middle E key which is weird but don’t worry about it. That’s just something I’ll deal with by eventually figuring out how to modify the project to fit new situations like the possibility of a keyboard split into 4 zones for piano four-hands or something. I need to understand modifying it deeply for the sake of it.

Thanks so much, Steve!

Yes I was pretty sure it was not perfect for your split point but should illustrate the concepts well. Hopefully with a bit of study, you can tweak it to work the way you want it. You should only need to change some rules in the last preset note off logic.

Steve

I was just thinking, I’m using the same offset on the upper half as the lower which is may not be correct as Octaves will definitely not be 64 semitones apart, Maybe make the upper octave 60 (4 lower semitoens) on the bitmap which would be 5 octaves (5x12) apart.

It might be a challenge on calculating the split points because I’m using all 32 bits of 4 variables (128 notes) and I believe the lowest note on most 88 key devices is note 21 and the highest is 108. With this the variables offsets in the lower note range will be different than the offsets in the upper note range using the variables I’ve set up.

Most of this discussion is way above that of normal free support provided here but hopefully the concepts can get you going. I’d have to think more about how I would implement this using less notes and a different split point to make the offsets more consistent.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Hi,
I played around with this a bit and came up with the attached result. Again not completely tested.

Strategy

Note-On

Convert all incoming note-ons above the split point 4 octaves down. If it is below note 21, discard it as it is out of range otherwise sound the note. For notes below the split point and 21 or greater, sound the note.
In both cases, if you want to convert the note to a higher note, maybe convert the note up a few octaves.

Note-Off

For note-off below the split point, look 4 octaves up (bitmap) to see if it is sounding, if it is, then do not send a note-off but if it isn’t, then send a note-off (again converting the outgoing as done with the note-on).
For note-off above the split point, look 4 octaves down to see if it is sounding, if it is, do not send a note-off but if it isn’t then send a note-off (with conversion as with note-on)

The main things I did to the last version

  1. Set up more global variables in translator 0.2
  2. Modified translators 2.1 and 2.2 to ignore notes below the low note and above the high note
  3. Re-wrote rules for 2.2 for strategy defined above.

The bitmapping of global variables g0-g3 has not changed.

Let me know how this works out.

Suppress-Split-Note-Off-2022-09-08.bmtp (6.1 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

This works great as far as I know with how it’s set up by default. Also the split isn’t a weird one so the C key on both sides of the split means a C note unlike before. One test I neglected to do with your last preset was with polyphony and this handles it like a champ. I tested it with two sets of four ‘identical’ notes on both sides of a split and the notes were held until the last note of its kind was released. The main problem is solved!

The only thing I had trouble with was understanding your exact design. Once I changed the variable “gb” corresponding to “number of notes per split point” assigning it to the value “12” I assumed that this would almost act similarly to a “key modulo” if that makes sense. What I mean by that is I figured changing it to 12 would make it so that I split the keyboard into every octave split possible and that no notes of the same octave class (whatever it’s called… every C, every C#, etc) would interrupt other notes with early or undesired note-offs. What happens is you get some weird hanging notes when crossing a split if I’m not mistaken about what’s happening.

I just need to set aside some time to look at it closer but it seems like all the necessary elements are here to work off of.
Thanks so much for your efforts, Steve!

Right,
I set it up for exactly 1 split point (as you had indicated in your requirements) and only look at the single note being played on the other side of the split point. I don’t check every octave so see if there is a note playing on each octave. This time you will be on your own but hopefully you can use my example to help get you going.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz