Does [midiout] send SysEx EOX if it is not present?

Peter Ostry's icon

For testing invalid SysEx in an Arduino,
I send this invalid SysEx string from a message box directly to [midiout] :
240 125 1 3 1 0
(247 at the end is missing)

But on the Mac, MIDI Monitor shows the complete, valid string
240 125 1 3 1 0 247

Well, Max tries to help, but is this behavior correct?
I think Max should not guess what I want to do but rather send what I say.

Source Audio's icon

What you see is not true for very first illegal sysex message.

Only when new one gets sent, previous one gets sealed.

similar with other broken midi messages.

You are not free to invent own midi rules.

Many efforts have been taken to protect

midi devices from corrupt midi messages.

Roman Thilenius's icon

regardless of that "auto-repair the first message when a new one is started" method, which is quite common, one could still implement a custom fix to complete broken messages (and if you do, the one built into midiout, a third party app or an OS will never execute, and you have full control about your data again.)

otoh, there can be different reasons why a message is incomplete, and therefore there could be more bytes missing than only the sysex-end.
would one like that to be autorepaired by the sending device or a max software?

it might be wrong in terms of the midi spec, but i share the opinion of the OP that this decision should be left to the receiving device.

Peter Ostry's icon

Not sure if MIDI targets need protection by closing a SysEx string automatically. Are they not supposed to refuse processing and/or timeout if they do not receive EOX? But who knows, maybe some don’t and we might overload or kill them.

On the other hand, we don't see our mistake when our usual MIDI monitors show the auto-corrected string and that can have other effects.

I already see too much auto-correction everywhere, also in DAWs.
I'm rather with Roman, because he takes the same pigheaded approach as I do :-)

But for the sake of peace and quiet, I accept Max's protective instinct and will ruin my test SysEx more creatively in future.

Source Audio's icon

I personally don't care much, just take it as it is.

And anyway there where it can get critical,

with sysex dumps, better made hardware would allways use checksum to drop

faulty messages.

Roman Thilenius's icon

i´ve read it up and as it seems it should not be completed automatically, which makes sense because nobody can know when a sysex message is finished, i.e. there could be missing more than the end byte.

given that you are sending a list to midiout this seems to make the difference; if you would send sysex byte by byte to midiout it will not add anything.

so i guess it is time to add some commas or an iter to your test data. :)

data types for midiout is either/or, you are not supposed to send "240 125 1 3 1 0, 247"

Source Audio's icon

what i don't see is what is the sense to send faulty sysex messages in first place ?

but if list or itered , no difference that I can observe.

question is more what is most common reason for mistakes when forming midi messages.

and again, uncomplete sysex does not get finished unless some other status byte gets sent

Peter Ostry's icon

Confirmed, itering does not change the behavior. I tried pauses of several seconds and although the result varies (cache/processing in midiout), it seems practically impossible to control EOX. From a midiout point of view, it does a good job.

Why send faulty SysEx? Simply to test. I am making a Max Editor for an Arduino application and it communicates via custom SysEx. I wanted to see the reaction if the SysEx was wrong. The fact that I removed EOX was a coincidence. I just wanted to break something in the string except the length, because the Arduino code catches a wrong length.

In fact, I have tried to design a receiver in the way that is expected of it, namely to catch mistakes. But Max doesn't allow my mistakes, which I have to accept with a certain ambivalence.

Source Audio's icon

you can well create faulty sysex sender,

just use another arduino, or use arduino as serial device.

Midi is anyway nothing else then series of bytes.

Peter Ostry's icon

Oh yes, my very first Arduino and then a second one to shoot down the first one ... no, I'm glad I got it to work the way it might. It wasn't as easy as I thought with ChatGPT for C code. You're a supervisor, nurse, psychotherapist and logic analyser at the same time. I cancelled the guy several times and changed the guidance technique to get a proper code. But it seems to have worked (fingers crossed).

Source Audio's icon

I think using that chat shit is worst ever thing if one wants to learn something properly

Roman Thilenius's icon

moment, again, how would midiout know when the sysex string is complete? that is confusing.

Peter Ostry's icon

Learning with the Bot is certainly difficult if you don't know anything about programming. But if you know other languages and the methodology and don't want to spend a lot of time learning the stuff, or buy the programming, even a public Bot works reasonably well for C/C++.

But you have to force him to follow your structure and logic. Otherwise he'll inflate your project with crazy ideas and absurd fixes until it's broken and irreparable. He did that to me twice until I learnt to be a dictator.

Writing complete programs is too difficult for a Bot. You can also upload a piece of code and say ‘find the error’. The Bot is pretty good at that and explains what's wrong. On request, it rewrites the code straight away. This is one of the reasons why more and more companies are programming with Bots as virtual employees.

But back to the topic.

If you want, just ask ChatGPT this question:
"When I send invalid SysEx from Max, a list directly into midiout, Max completes it automatically with EOX. I want to test, don't want auto-completion. Why does Max do this and can I do something against?"

You may be surprised to get a competent and detailed answer within seconds, with only a few mistakes, although Bots know very little about Max, too little to really work with.

Peter Ostry's icon

Roman:
"moment, again, how would midiout know when the sysex string is complete? that is confusing."

It recognizes the 240 at the start and something else after it and if there is no 247 for a while it adds a 247 and sends the data out. In my tests midiout waited up to 5 seconds but the timing varies greatly. Looks as if it adapts to the speed of the individual numbers and there is some cache involved. Or maybe it calls Cycling'74 for help? If I send only 240, I get instantly 240 247.

Roman Thilenius's icon

but "instantly" can´t be, isn´t it? it must be a time out value.

edit: ah well, i was thinking about "240" not beeing a list... but of course midiout still knows what it means. :)

interesting enough, sxformat does not automatically add it - you would rather expect it there than in the midiout family.

Peter Ostry's icon

Yes, I was surprised too. I thought if you send directly to midiout you get the ‘rawest’ output without manipulation. But as a protection mechanism it has to be in midiout because that is the last accessible point before the output.

Roman Thilenius's icon

well, it explains why sysex has to be sent as list to midiout while most other things work bytewise.

Peter Ostry's icon

Normally it should be a string, yes.

It probably also works sequentially if you send to midiout so quickly that you stay below the timing threshold. I haven't tried this, but it could be interesting for some applications.

New finding – There is a cache involved that I don't appreciate:
I had closed the test patch from yesterday unsaved, Max was still open. Today I made a new patch, a message box with 240 and a midiout and started the MIDI Monitor on the Mac. Clicking on the message box showed me the last test sequence from yesterday in MIDI Monitor. It didn't come from MIDI Monitor, that was new. It couldn't have come from the old midiout either, because this was gone with the old patch. The cache apparently lives in a MIDI output function of Max. A new patch sends data from yesterday? That's not what we want under any circumstances.

Now I have challenged the ‘protection function’ and sent invalid strings "240 <random>" to midiout with an interval of several seconds (manual click):

The output was pretty funny:

Sometimes F0 F7 came up, sometimes no line, sometimes two, sometimes the algorithm was so confused that it constructed completely different data. I think the English-speaking people say ‘it went haywire’.

You could say that it would be ridiculous to make such a fuss because some idiot deliberately dropped the last byte. But it can happen to anyone and the result is, in my opinion, unacceptable.

How can this be done better?

I would remove the entire ‘protection function’ and the associated cache and replace it with something else.

If no 247 arrives in midiout after 240 within a certain time, either nothing should be sent at all, or something should happen that tells the user that there is a SysEx error. But how? There is no MIDI error message. Sending F0 0 F7 as an error message probably wouldn't hurt anyone, but it doesn't make troubleshooting any easier. Maybe midiout should not send anything but needs an output that indicates errors. Doesn't have to act overly clever, can be a bang or 0/1 or a printable message. Since I don't normally send raw MIDI for CC, PC, Notes etc and don't know if that is controlled by Max as well, maybe the midiout output could be used for those as well.

According to my philosophy, I am in favour of everything the user does being sent. However, the supervisor of my philosophy says that the counter arguments must be taken into account. The practitioner in me says that nothing should be sent at all. The boss of the practitioner in me says that this is unfavourable because the user won't see anything. I could argue with myself for years. So, Cycling'74, please do it differently than it is now and make it as simple as possible.

Roman Thilenius's icon

i do not really see a counter argument for autocompletion of faulty sysex, this might have a good reason. but it is somehow inconsequent, because it does not do this for notes, controllers, or NRPNs.

a sysex message is only complete and can only execute something in the receiving device when it is complete. so midiout makes it complete. so far so good.
a note message without note on velocity value is also incomplete and useless. but midiout does not make it complete, you can send it "144", "60" or "144 60" - and nothing happens as long as the third byte is missing.

a possible alternative for closing sysex with EOX would be to not send the data out at all, just as it happens with channel and voice messages.

Peter Ostry's icon

Roman wrote:
i do not really see a counter argument for autocompletion of faulty sysex

I'm willing to agree with that and also to throw some of what I wrote above into the rubbish bin as ‘too nerd-ish’. But the output cache and its processing is annoying. Simply adding F0 would be ok. But memorising values and putting them together differently for the next dispatch is not ok.