Some OSS sequencer events and
ioctl(2) operations are unimplemented, as
<sys/midiio.h> notes.
OSS source-compatible sequencer macros should be added to
<sys/soundcard.h>, implemented with the
NetBSD ones in
<sys/midiio.h>, so sources written for OSS can be easily compiled.
The sequencer blocks (or returns
EWOULDBLOCK) only when its buffer physically fills, which can represent an arbitrary latency because of buffered timing events. As a result, interrupting a process writing the sequencer may not interrupt music playback for a considerable time. The sequencer could enforce a reasonable latency bound by examining timing events as they are enqueued and blocking appropriately.
FIOASYNC enables signal delivery to the calling process only;
FIOSETOWN is not supported.
The sequencer can only be a timing master, but does not send timing messages to synchronize any slave device; it cannot be slaved to timing messages received on any interface (which would presumably require a PLL algorithm similar to NTP's, and expertise in that area to implement it). The sequencer ignores timing messages received on any interface and does not pass them along to the reading process, and the OSS operations to change that behavior are unimplemented.
The
SEQUENCER_TMR_TIMEBASE ioctl(2) will report successfully setting any timebase up to ridiculously high resolutions, though the actual resolution, and therefore jitter, is constrained by
hz(9). Comparable sequencer implementations typically allow a selection from available sources of time interrupts that may be programmable.
The device number in a sequencer event is treated on
write(2) as index into the array of MIDI devices the sequencer has opened, but on
read(2) as the unit number of the source MIDI device; these are usually the same if the sequencer has opened all the MIDI devices (that is, none was already open at its raw node when the sequencer was opened), but might not be the same otherwise.
There is at present no way to make reception nonpromiscuous, should anyone have a reason to want to.
There should be ways to override default Active Sense behavior. As one obvious case, if an application is seen to send Active Sense explicitly,
midi should refrain from adding its own. On receive, there should be an option to pass Active Sense through rather than interpreting it, for apps that wish to handle or ignore it themselves and never see
EOF.
When a
midi stream is open by the sequencer, Active Sense messages received on the stream are passed to the sequencer and not interpreted by
midi. The sequencer at present neither does anything itself with Active Sense messages received, nor supports the OSS API for making them available to the user process.
System Exclusive messages can be received by reading a raw device, but not by reading the sequencer; they are discarded on receipt when the stream is open by the sequencer, rather than being presented as the OSS-defined sequencer events.
midisyn is too rudimentary at present to get satisfactory results from any onboard synth. It lacks the required special interpretation of the General MIDI percussion channel in GM mode. More devices should be supported; some sound cards with synthesis capability have
NetBSD drivers that implement the
audio(4) but not the
midisyn interface. Voice stealing algorithm does not follow the General MIDI Developer Guidelines.
ALSA sequencer compatibility is lacking, but becoming important to applications. It would require the function of merging multiple tracks into a single ordered stream to be moved from user space into the sequencer. Assuming the sequencer driven by periodic interrupts, timing wheels could be used as in
hardclock(9) itself. Similar functionality will be in OSS4; with the right infrastructure it should be possible to support both. When merging MIDI streams, a notion of transaction is needed to group critical message sequences. If ALSA or OSS4 have no such notion, it should be provided as an upward-compatible extension.
I would rather have
open(2) itself return an error (by the POSIX description
ENODEV looks most appropriate) if a read or write mode is requested that is not supported by the instance, rather than letting
open(2) succeed and
read(2) or
write(2) return -1, but so help me, the latter seems the more common
UNIX practice.