The midi driver makes MIDI ports available to
user applications. A midi device
corresponds to 2 MIDI ports: one input port and one output port. Data received
on the input port is not interpreted and is passed to the user program as-is.
Similarly, data issued by the user program is sent as-is to the output port.

Only one process may hold open a midi device
at a given time, although file descriptors may be shared between processes
once the first open completes. If it is opened read-only (write-only) only the
input (output) MIDI port is available.

A process can send raw MIDI data to the output port by using the
write(2) system call. Data is
queued and the system call returns immediately; the data is sent as fast as
possible to the output MIDI port. However, if the in-kernel buffer is full or
the requested amount is too large, then
write(2) may block. The current
size of the in-kernel buffer is 1024 bytes, which ensures that
write(2) isn't blocking in most
situations.

Data received from the input MIDI port is stored into the in-kernel buffer. A
process can retrieve its contents by using the
read(2) system call. If there is
less data than the amount requested for reading, then a shorter amount is
returned. If no data is available, then the
read(2) system call will block
until data is received, and then return immediately.

The MIDI protocol has been designed for real-time performance and doesn't
support flow control. An application must be able to read the incoming data
fast enough (the MIDI standard's maximum rate is 3125 bytes per second). The
kernel can buffer up to 1024 bytes; once the buffer is full input will be
silently discarded.

If the midi device is opened with the
O_NONBLOCK flag (see open(2)),
then subsequent calls to read(2)
or write(2) will never block. The
write(2) system call may write
less bytes than requested, or may return EAGAIN if no data could be sent or
queued. Similarly, the read(2)
system call may return EAGAIN if no input is available.

Note that even if non-blocking I/O is not selected,
read(2) and
write(2) system calls are
non-blocking when the kernel buffers permit it.

MIDI hardware was designed for real time performance and software using such
hardware must be able to process MIDI events without any noticeable latency
(typically no more than 5ms, which is the time it takes for sound to propagate
1.75 meters).

The OpenBSDmidi
driver processes data fast enough, however if a MIDI application tries to
write data faster than the hardware is able to process it (typically 3125
bytes per second), then kernel buffers may become full and the application may
be blocked.

The other common reason for MIDI data being delayed is the system load.
Processes cannot be preempted while running in kernel mode. If there are too
much processes running concurrently (especially if they are running a lot of
expensive system calls) then the scheduling of a real-time MIDI application
may be delayed. Even on low-end machines this delay hardly reaches a few
milliseconds provided that the system load is reasonable.

A real-time MIDI application can avoid being swapped by locking its memory (see
mlock(2) and
mlockall(2)).

For a given device, even if the physical MIDI input and output ports are
independent, there is no way for one process to use the input MIDI port and
for another process to use the output MIDI port at the same time.