Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MIDI(4)		       FreeBSD Kernel Interfaces Manual		       MIDI(4)

NAME
     midi -- raw device	independent interface to MIDI ports

SYNOPSIS
     midi* at autri?
     midi* at eap?
     midi* at envy?
     midi* at mpu?
     midi* at sb?
     midi* at umidi?
     midi* at ym?

DESCRIPTION
     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 com-
     pletes.  If it is opened read-only	(write-only) only the input (output)
     MIDI port is available.

   Writing to the device
     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.

   Reading from	the device
     Data received from	the input MIDI port is stored into the in-kernel buf-
     fer.  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 immedi-
     ately.

     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 sec-
     ond).  The	kernel can buffer up to	1024 bytes; once the buffer is full
     input will	be silently discarded.

   Polling the device
     A process can use the poll(2) system call to poll for the following
     events:

     POLLIN   The in-kernel input buffer isn't empty, i.e. at least one	byte
	      is available for reading.	 A subsequent call to read(2) will not
	      be blocking.

     POLLOUT  The in-kernel output buffer is empty, thus a subsequent call to
	      write(2) will not	be blocking if a reasonable amount of data is
	      written (currently less that 1024	bytes).

     Using the poll(2) system call is the recommended way to handle multiple
     midi devices in a real-time MIDI application.

   Non-blocking	I/O
     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.

FILES
     /dev/rmidi*  midi devices

EXAMPLES
     The following command could record	the memory dump	of a synthesizer in a
     file:

	   $ cat -u /dev/rmidi2	>dumpfile

     A MIDI keyboard could be connected	to a synthesizer by the	command:

	   $ cat -u /dev/rmidi1	>/dev/rmidi2

     The input port could be connected to the output port by the command:

	   $ cat -u <>/dev/rmidi1 >&0

     The following example reads MIDI timing events from an input device, MIDI
     common and	voice events from another input	device,	and sends the result
     to	a third	(output) device.

	   #define BUFSIZE	   0x100
	   #define ISTIMING(c)	   ((c)	== 0xf8	|| (c) == 0xfa || (c) == 0xfc)
	   #define ISCOMMON(c)	   ((c)	< 0xf8)

	   int ofd;
	   struct pollfd ifd[2];
	   unsigned char ibuf[BUFSIZE],	obuf[2 * BUFSIZE];
	   ssize_t iused, oused, i;

	   ifd[0].events = ifd[1].events = POLLIN;
	   for (;;) {
		   oused = 0;
		   if (poll(ifd, 2, -1)	== -1)
			   errx(1, "poll");
		   if (ifd[0].revents &	POLLIN)	{
			   if ((iused =	read(ifd[0].fd,	ibuf, BUFSIZE))	== -1)
				   errx(1, "read");
			   for (i = 0; i < iused; i++)
				   if (ISTIMING(ibuf[i]))
					   obuf[oused++] = ibuf[i];
		   }
		   if (ifd[1].revents &	POLLIN)	{
			   if ((iused =	read(ifd[1].fd,	ibuf, BUFSIZE))	== -1)
				   errx(1, "read");
			   for (i = 0; i < iused; i++)
				   if (ISCOMMON(ibuf[i]))
					   obuf[oused++] = ibuf[i];
		   }
		   if (write(ofd, obuf,	oused) == -1)
			   errx(1, "write");
	   }

     In	the above example, unless kernel buffers are full, processing is done
     in	real-time without any noticeable latency; as expected, the only	block-
     ing system	call is	poll(2).

ERRORS
     If	open(2), read(2), write(2), or poll(2) fail then errno(2) may be set
     to	one of:

     [ENXIO]		The device is opened read-only (write-only) but
			write(2) (read(2)) was called.

     [EIO]		The device is being detached while a process has been
			trying to read or write	(for instance an umidi(4) de-
			vice has been unplugged).

     [EAGAIN]		Non-blocking I/O was selected and the output buffer is
			full (on writing) or the input buffer is empty (on
			reading).

     [EBUSY]		The device is already open by another process.

SEE ALSO
     autri(4), eap(4), envy(4),	mpu(4),	sb(4), umidi(4)

HISTORY
     The midi driver first appeared in OpenBSD 2.5.

AUTHORS
     The midi driver was originally written by Lennart Augustsson and later
     largely rewritten by Alexandre Ratchov.

CAVEATS
     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 OpenBSD midi driver processes data fast enough, however if a MIDI ap-
     plication 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 mem-
     ory (see mlock(2) and mlockall(2)).

BUGS
     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.

FreeBSD	13.0			August 31, 2016			  FreeBSD 13.0

NAME | SYNOPSIS | DESCRIPTION | FILES | EXAMPLES | ERRORS | SEE ALSO | HISTORY | AUTHORS | CAVEATS | BUGS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=midi&sektion=4&manpath=OpenBSD+6.9>

home | help