Transposing incoming MIDI notes

I have a control that allows the user to transpose the incoming Midi notes. My plugin also has an onscreen keyboard component that uses a MidiKeyboardState. The MidiKeyboardState merges the incoming Midi stream with the new notes generated by clicking the onscreen keyboard…but I need to transpose the incoming Midi and not the component generated notes.

I’m not sure what the most efficient way is to transpose MidiMessages in a MidiBuffer. It looks like MidiBuffer::Iterator just gives a copy of the MidiMessage and I don’t see a way to replace a single MidiMessage.

Given that, it seems I have to have another MidiBuffer, read noteOns from the original, transpose it and add it to the other MidiBuffer but I have to wonder about memory allocation. It would be great to just be able to transpose a Midi noteOn message in place but that doesn’t seem to be an option.

So…what’s the most efficient way to do this?

Well, the correct way to do this is to copy the items to a new buffer, but if you’re only modifying the pitches, that does seem like a lot of work… You could const_cast the iterator’s pointer and poke the bytes directly, but I wouldn’t officially recommend you to do that in case we ever change the way it works in a way that prevents that hack from working…

True…neither solution sounds ideal. It would be great if there was an official way to do this. Like, maybe a MidiBuffer::Iterator function that returns a pointer to the MidiMessage instead of a copy?

It can’t do that - there isn’t actually MidiMessage object inside the buffer, it’s just a packed series of midi bytes. That’s why it doesn’t let you edit them in-place, otherwise it’d need to shuffle the subsequent messages along if you change the size of one of them.

TBH for normal buffers, making a copy will be very quick. If I were you I’d do it that way and only worry about optimising later if you need to.

You’re right. I just made a function that loops through the original MidiBuffer, copying events to another buffer and transposing them if they’re note events. Definitely cleaner. My tendency is to always think about moving the least amount of bytes around and sometimes I get caught in the weeds for very little extra CPU time. Thanks for putting me on the right track, @jules .