How do I receive Sysex Messages - do I have to go around the parser ?
It would be nice with a Sysex callback
How do I receive Sysex Messages - do I have to go around the parser ?
It would be nice with a Sysex callback
see if this works for you (on the dev
branch) https://github.com/BelaPlatform/Bela/commit/571900b4f1feb453a3a4f61f5790f530cdb21272
That works fine
If it was up to me, the callback would have a std::vector<midi_byte_t> sysexMessage
with the relevant bytes between the start byte 240 and endbyte 247 as argument. The callback would then only fire when the endbyte is received and the message is complete... Just a suggestion...
Thanks for being so fast with solutions always !
That was my first thought, but there are a number of implications. One problem is that there is no guarantee as to what thread this callback would run on: depending on the rest of the code, it could run in the audio thread or in another thread. In case it runs in the audio thread, resizing a std::vector
would not be RT-safe. Additionally, sysex blocks could be very large but you may process the data in smaller chunks. For instance, if you are receiving a large parameter dump where the information is organised in 4 bytes per parameter, you wouldn't need to store all the content of the dump and only process it all at once, but you could process every block of 4 bytes at at time. In another case, you can also samples via sysex, what would be the point of caching in memory several megabytes of samples to then process them and write them to disk one at a time? Some applications (e.g.: libpd) require to pass one byte at a time, so this is the most generic solution.
Ultimately, if you want to achieve the behaviour you mentioned, you can with this API, with just a couple of extra lines of code E.g.:
void sysexCallback(midi_byte_t byte, void*arg)
{
auto sysexIn = (std::vector<midi_byte_t>*)arg;
if(0xF0 == byte) {
/// end of message
// do something with its content ...
/// ... then empty it
sysexIn->resize(0);
}
else
sysexIn->push_back(byte);
}
// this must be in a valid state at all times while the callback is called. For instance, make it global.
std::vector<midi_byte_t> gSysexIn;
bool setup(...) {
...
// I pass it as an argument here because it's good practice and it helps when you are using the same callback to
// act on different objects, but if you only have one object, you could just access the global variable from the callback
midi.setSysexCallback(sysexCallback, (void*)&gSysexIn);
...
}
Thinking more about it and reading your arguments I agree Thnx