Subject: Re: [long] Re: RFC: merge chap-midi branch
To: Alexandre Ratchov <alex@caoua.org>
From: Chapman Flack <nblists@anastigmatix.net>
List: tech-kern
Date: 06/28/2006 16:28:33
Alexandre Ratchov wrote:
>>signalled for you by a zero-byte read(2), i.e. a one-shot EOF indication,
>>much like the handling of ^D by termios(4).  You are free to continue
>>reading afterward; the channel will have reverted to non-Active-Sensing
> 
> if i'm not mistaken, 
> 
> 	cat /dev/rmidiN >/tmp/xxx
> 
> will stop working on the first error, but will not restart
> working when the cable is plugged again.

s/error/Active Sense timeout/ and yes, exactly; that is nearly verbatim
the example from the man page. The point here is, if you are using a
general utility like 'cat' rather than some midi-aware program, your
choices for what you would want it to do in this case are limited to
about two. You can get a file xxx that contains the known good data up
to a break in communication, or you could get a file xxx that contains a
time warp at some unspecified spot where some unknown amount of data
dropped out and you don't know what happened to the state. If the
first is what you want, use the command above.  If it's the second you
want, use

  while cat; do :; done </dev/rmidiN >/tmp/xxx

If what you want is more sophisticated than either of those, 'cat' might
not be what you want.  But you might notice two things:

1- the second choice actually extends rather easily to things like
   while cat; do print -r "$RESET_ALL"; done </dev/rmidiN >/tmp/xxx
   or
   while cat >/tmp/xxx$((segno++)); do :; done </dev/rmidiN

2- if I had not implemented Active Sense as I did, you might not have
   even this range of choices available to you as simple one-liners of
   Unix tools.

> doesn't the midi sensing single-byte message fit in your definition of
> midi message?

Touché.  Yes, for sheer consistency it could be desirable to have an
option to be Active Sense-transparent and leave it all to the
application; that's mentioned on the man page, and not implemented yet.
But please remember that the status quo ante was this:

  281:        if (data == MIDI_ACK)
  282:                return;

That is, Active Sense was completely swallowed in the driver. The driver
did not handle the monitoring for you, and you had no possibility of
doing it yourself because you would never see the message. And that
accurately replicated the OSS behavior. :/

That is, of the three general choices available for handling Active
Sense:

  1  Handle in driver
  2  Pass transparently and make it application's problem
  3  Punt

the original choice was (3), the only completely untenable one. :) So it
had to change. You'll notice that neither change 3->1 nor 3->2 can be
made with zero compatibility impact.  Change from 3->2
and apps are suddenly reading a lot of MIDI messages they would not have
seen before and with which they may not have been tested--reading
them constantly, under normal operating conditions. Change from 3->1 and
apps may be faced with some chosen timeout signal (EOF, by my choice)
that they would not have expected--but that only under exceptional
conditions, and there is some hope that for many programs a naive
response to the signal will be something reasonable. The EOF signal is
also quite easy to code for in a new application, and gives you the
flexibility you saw above to do reasonable things with standard Unix
tools.

I hope that helps you see why I made the choices I did. I agree that
a fully transparent Active Sense mode could also be useful, selectable
by an application that really intends to use it (so applications that
don't will at least get the default support in the driver). I don't have
immediate plans to add it though, and when I do I will probably work
on the transmit side first.

-Chap