summaryrefslogtreecommitdiff
path: root/static/netbsd/man4/midi.4
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man4/midi.4')
-rw-r--r--static/netbsd/man4/midi.4771
1 files changed, 771 insertions, 0 deletions
diff --git a/static/netbsd/man4/midi.4 b/static/netbsd/man4/midi.4
new file mode 100644
index 00000000..3e33ae5f
--- /dev/null
+++ b/static/netbsd/man4/midi.4
@@ -0,0 +1,771 @@
+.\" $NetBSD: midi.4,v 1.32 2017/07/03 21:30:58 wiz Exp $
+.\"
+.\" Copyright (c) 1999-2017 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Lennart Augustsson and Chapman Flack.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd April 28, 2017
+.Dt MIDI 4
+.Os
+.Sh NAME
+.Nm midi
+.Nd device-independent MIDI driver layer
+.Sh SYNOPSIS
+.Cd "midi* at midibus?"
+.Cd "midi* at pcppi?"
+.Cd "pseudo-device sequencer"
+.Pp
+.In sys/types.h
+.In sys/midiio.h
+.Sh DESCRIPTION
+The
+.Nm
+driver is the machine independent layer over anything that can
+source or sink a
+.Tn MIDI
+data stream, whether a physical
+.Tn "MIDI IN"
+or
+.Tn "MIDI OUT"
+jack on a soundcard, cabled to some external synthesizer or input controller,
+an on-board programmable tone generator, or a single jack, synthesizer, or
+controller component within a complex
+.Tn USB
+or
+.Tn IEEE1394
+.Tn MIDI
+device that has several
+such components and appears as several
+.Tn MIDI
+streams.
+.Ss Concepts
+One
+.Tn MIDI
+data stream is a unidirectional stream of
+.Tn MIDI
+messages, as could be carried over one
+.Tn MIDI
+cable in the
+.Tn "MIDI 1.0"
+specification.
+Many
+.Tn MIDI
+messages
+carry a four-bit channel number, creating up to 16
+.Tn MIDI
+channels within a single
+.Tn MIDI
+stream.
+There may be multiple consumers of a
+.Tn MIDI
+stream, each configured
+to react only to messages on specific channels; the sets of channels different
+consumers react to need not be disjoint.
+Many modern devices such as multitimbral keyboards and tone generators
+listen on all 16 channels, or may be viewed as collections of 16
+independent consumers each listening on one channel.
+.Tn MIDI
+defines some messages that take no channel number, and
+apply to all consumers of the
+stream on which they are sent.
+For an inbound stream,
+.Nm
+is a promiscuous
+receiver, capturing all messages regardless of channel number.
+For an outbound stream, the writer can specify a channel number
+per message; there is no notion of binding the stream to one
+destination channel in advance.
+.Pp
+A single
+.Nm
+device instance is the endpoint of one outbound stream, one
+inbound stream, or one of each.
+In the third case, the write and read sides are independent
+.Tn MIDI
+streams.
+For example, a soundcard driver may map its
+.Tn "MIDI OUT"
+and
+.Tn "MIDI IN"
+jacks to the write and read sides of a single device instance, but
+those jacks can be cabled to completely different pieces of gear.
+Information from
+.Xr dmesg 8 ,
+and a diagram of any external
+.Tn MIDI
+cabling, will help clarify the mapping.
+.Ss "Underlying drivers and MIDI protocol"
+Drivers
+.Nm
+can attach include soundcard drivers, many of
+which support a
+.Tn UART
+resembling Roland's
+.Tn MPU401
+and handled by
+.Xr mpu 4 ,
+.Tn "USB MIDI"
+devices via
+.Xr umidi 4 ,
+and on-board devices that can make sounds,
+whether a lowly
+.Tn PC
+speaker or a Yamaha
+.Tn OPL .
+Serial port and
+.Tn IEEE1394
+connections are currently science fiction.
+.Pp
+The
+.Tn MIDI
+protocol permits some forms of message compression such as running
+status and hidden note-off.
+Received messages on inbound streams are always canonicalized by
+.Nm
+before presentation to higher layers.
+Messages for transmission are accepted by
+.Nm
+in any valid form.
+.Ss "Device access"
+Access to
+.Nm
+device instances can be through the raw device nodes,
+.Pa /dev/rmidiN ,
+or through the sequencer,
+.Pa /dev/music .
+.Ss "Raw MIDI access"
+A
+.Pa /dev/rmidiN
+device supports
+.Xr read 2 ,
+.Xr write 2 ,
+.Xr ioctl 2 ,
+.Xr select 2 Ns / Ns
+.Xr poll 2
+and the corresponding
+.Xr kevent 2
+filters,
+and may be opened
+only when it is not already open.
+It may be opened in
+.Dv O_RDONLY ,
+.Dv O_WRONLY ,
+or
+.Dv O_RDWR
+mode, but a later
+.Xr read 2
+or
+.Xr write 2
+will return \-1 if the device has no associated
+input or output stream, respectively.
+.Pp
+Bytes written are passed as quickly as possible to the underlying driver
+as complete
+.Tn MIDI
+messages; a maximum of two bytes at the end of a
+.Xr write 2
+may remain buffered if they do not complete a message, until
+completed by a following
+.Xr write 2 .
+.Pp
+A
+.Xr read 2
+will not block or return
+.Er EWOULDBLOCK
+when it could immediately return any nonzero count, and
+.Tn MIDI
+messages received are available to
+.Xr read 2
+as soon as they are complete,
+with a maximum of two received bytes remaining buffered if they do not
+complete a message.
+.Pp
+As all
+.Tn MIDI
+messages are three bytes or fewer except for System Exclusive,
+which can have arbitrary length, these rules imply that System Exclusive
+messages are the only ones of which some bytes can be delivered before
+all are available.
+.Pp
+System Realtime messages are passed with minimum delay in either direction,
+ahead of any possible buffered incomplete message.
+As a result, they will never interrupt any
+.Tn MIDI
+message except possibly System Exclusive.
+.Pp
+A
+.Xr read 2
+with a buffer large enough to accommodate the first complete
+message available will be satisfied with as many complete messages as
+will fit.
+A buffer too small for the first complete
+message will be filled to capacity.
+Therefore, an application that reads from an
+.Pa rmidi
+device with buffers of three bytes or larger need never parse
+across read boundaries to assemble a received message, except possibly in
+the case of a System Exclusive message.
+However, if the application reads through a buffering layer such as
+.Xr fread 3 ,
+this property will not be preserved.
+.Pp
+The
+.Nm
+driver itself supports the
+.Xr ioctl 2
+operations
+.Dv FIOASYNC ,
+.Dv FIONBIO ,
+and
+.Dv FIONREAD .
+Underlying devices may support others.
+The value returned for
+.Dv FIONREAD
+reflects the size in bytes of complete messages
+(or System Exclusive chunks) ready to read.
+If the
+.Xr ioctl 2
+returns
+.Va n
+and a
+.Xr read 2
+of size
+.Va n
+is issued,
+.Va n
+bytes will be read, but if a
+.Xr read 2
+of
+size
+.Va m
+<
+.Va n
+is issued, fewer than
+.Va m
+bytes may be read if
+.Va m
+does not fall
+on a message/chunk boundary.
+.Pp
+Raw
+.Tn MIDI
+access can be used to receive bulk dumps from synthesizers, download
+bulk data to them, and so on.
+Simple patching of one device to another can be
+done at the command line, as with
+.Dl $ cat -u 0<>/dev/rmidi0 1>&0
+which will loop all messages received on the input stream of
+.Pa rmidi0
+input stream back to its output
+stream in real time.
+However, an attempt to record and play back music with
+.Dl $ cat /dev/rmidiN >foo; cat foo >/dev/rmidiN
+will be disappointing.
+The file
+.Pa foo
+will contain all of the notes that were played, but because
+.Tn MIDI
+messages carry
+no explicit timing, the
+.Sq "playback"
+will reproduce them all at once, as fast as
+they can be transmitted.
+To preserve timing information, the sequencer device can be used.
+.Ss "Active Sensing"
+The
+.Tn MIDI
+protocol includes a keepalive function called Active Sensing.
+In any receiver that has
+.Em not
+received at least one Active Sense
+.Tn MIDI
+message, the
+feature is suppressed and no timeout applies.
+If at least one such message has
+been received, the lapse of any subsequent 300 ms interval without receipt of
+any message reflects loss of communication, and the receiver should silence any
+currently sounding notes and return to non-Active-Sensing behavior.
+A sender using Active Sensing generally avoids 300 ms gaps in
+transmission by sending Active Sense messages (which have no other
+effect) as needed when there is no other traffic to send in the
+interval.
+This feature can be important for
+.Tn MIDI ,
+which relies on separate Note On and Note Off messages, to avoid notes stuck on
+indefinitely if communication is interrupted before a Note Off
+message arrives.
+.Pp
+This protocol is supported in
+.Nm .
+An outbound stream will be kept alive
+by sending Active Sense messages as needed, beginning after any real
+traffic is sent on the stream, and continuing until the stream is closed.
+On an inbound stream, if any Active Sense has been received, then a process
+reading an
+.Pa rmidi
+device will see an end-of-file indication if the input timeout elapses.
+The stream remains open, the driver reverts to enforcing no timeout, and the
+process may continue to read for more input.
+Subsequent receipt of an
+Active Sense message will re-arm the timeout.
+As received Active Sense messages are handled by
+.Nm ,
+they are not included among messages read from the
+.Pa /dev/rmidiN
+device.
+.Pp
+These rules support end-to-end Active Sensing behavior in simple cases
+without special action in an application.
+For example, in
+.Dl $ cat -u /dev/rmidi0 >/dev/rmidi1
+if the input stream to
+.Pa rmidi0
+is lost, the
+.Xr cat 1
+command exits; on the
+.Xr close 2
+of
+.Pa rmidi1 ,
+.Nm
+ceases to send Active Sense messages, and the receiving
+device will detect the loss and silence any outstanding notes.
+.Ss "Access through the sequencer"
+To play music using the raw
+.Tn MIDI
+.Tn API
+would require an application to
+issue many small writes with very precise timing.
+The sequencer device,
+.Pa /dev/music ,
+can manage the timing of
+.Tn MIDI
+data in the kernel, to avoid
+such demanding real-time constraints on a user process.
+.Pp
+The
+.Pa /dev/music
+device can be opened only when it is not already open.
+When opened, the sequencer internally opens all
+.Tn MIDI
+instances existing
+in the system that are not already open at their raw nodes; any attempts
+to open them at their raw nodes while the sequencer is open will fail.
+All access to the corresponding
+.Tn MIDI
+streams will then be through the
+sequencer.
+.Pp
+Reads and writes of
+.Pa /dev/music
+pass eight-byte event structures defined in
+.In sys/midiio.h
+(which see for their documentation and examples of use).
+Some events correspond to
+.Tn MIDI
+messages, and carry an integer
+.Va device
+field to identify one of the
+.Tn MIDI
+devices opened by the sequencer.
+Other events carry timing information interpreted or generated by the
+sequencer itself.
+.Pp
+A message received on an input stream is wrapped in a sequencer event
+along with the device index of the stream it arrived on, and queued for
+the reader of
+.Pa /dev/music .
+If a measurable time interval passed since the
+last preceding message, a timing event that represents a delay for that interval
+is queued ahead of the received event.
+The sequencer handles output events by
+interpreting any timing event, and routing any
+.Tn MIDI
+message event at the proper time to
+an underlying output stream according to its
+.Va device
+index.
+Therefore
+.Dl $ cat /dev/music >foo; cat foo >/dev/music
+can be expected to capture and reproduce an input performance including
+timing.
+.Pp
+The process of playing back a complex
+.Tn MIDI
+file is illustrated below.
+The file may contain several tracks\(emfour, in this example\(emof
+.Tn MIDI
+events, each marked with a device index and a time stamp, that may
+overlap in time.
+In the example,
+.Va a ,
+.Va b ,
+and
+.Va c
+are device indices of
+the three output
+.Tn MIDI
+streams; the left-hand digit in each input event represents a
+.Tn MIDI
+channel on the selected stream, and the right-hand digit represents
+a time for the event's occurrence.
+As illustrated, the input tracks are not firmly associated with
+output streams; any track may contain events for any stream.
+.Bd -literal
+ | | a2|4 |
+ a0|3 | c1|3 c0|3
+ | b0|2 b1|2 |
+ | b1|1 | c0|1
+ a0|0 | b0|0 |
+ v v v v
+ +---------------------------+
+ | merge to 1 ordered stream |
+ | user code, eg midiplay(1) |
+ +---------------------------+
+ b1|2
+ b0|2
+ c0|1
+ b1|1
+ b0|0
+ a0|0
+ v
+ _______+-------------+_______user
+ | /dev/music | kernel
+ | (sequencer) |
+ +-------------+
+ | 1 0
+ +-----' | '-----.
+ 0 0 |
+ v v v
+ +-------+ +--------+ +---------+
+ |midi(4)| |midi(4) | |midi(4) |
+ |rmidia | |rmidib | |rmidic |
+ +-------+ +--------+ +---------+
+ | mpu(4)| |umidi(4)| |midisyn |
+ +-------+ +--------+ +---------+
+ | HW | | | opl(4) |
+ | MIDI | U +---------+
+ | UART | S | internal|
+ +-------+ B | tone |
+ | | |generator|
+ v | +---------+
+ external v
+ MIDI device external
+ MIDI device
+.Ed
+.Pp
+A user process must merge the tracks into a single stream of sequencer
+.Tn MIDI
+and timing events in order by desired timing.
+The sequencer obeys the timing events and distributes the
+.Tn MIDI
+events to the three destinations,
+in this case two external devices connected to a sound card
+.Tn UART
+and a
+.Tn USB
+interface, and an
+.Tn OPL
+tone generator on a sound card.
+.Sh NOTES
+Use of
+.Xr select 2 Ns / Ns
+.Xr poll 2
+with the sequencer is supported, however, there is no guarantee that a
+.Xr write 2
+will not block or return
+.Er EWOULDBLOCK
+if it begins with a timer-wait event, even if
+.Xr select 2 Ns / Ns
+.Xr poll 2
+reported the sequencer writable.
+.Pp
+The delivery of a realtime message ahead of buffered bytes of an incomplete
+message may cause the realtime message to seem, in a saved byte stream, to have
+arrived up to 640 us earlier than it really did, at
+.Tn MIDI
+1.0 data rates.
+Higher data rates make the effect less significant.
+.Pp
+Another sequencer device,
+.Pa /dev/sequencer ,
+is provided only for backward
+compatibility with an obsolete
+.Tn OSS
+interface in which some sequencer events
+were four-byte records.
+It is not further documented here, and the
+.Pa /dev/music
+.Tn API
+should be used in new code.
+The
+.Pa /dev/sequencer
+emulation is implemented only for writing, and that might not be complete.
+.Sh IMPLEMENTATION NOTES
+Some hardware devices supporting
+.Nm
+lack transmit-ready interrupts, and some have the capability in
+hardware but currently lack driver support.
+They can be recognized by the annotation
+.Li "(CPU-intensive output)"
+in
+.Xr dmesg 8 .
+While suitable for music playback, they may have an objectionable impact on
+system responsiveness during bulk transmission such as patch downloads, and
+are best avoided for that purpose if other suitable devices are present.
+.Pp
+Buffer space in
+.Nm
+itself is adequate for about 200 ms of traffic at
+.Tn "MIDI 1.0"
+data rates, per stream.
+.Pp
+Event counters record bytes and messages discarded because of protocol
+errors or buffer overruns, and can be viewed with
+.Li "vmstat -e" .
+They can be useful in diagnosing flaky cables and other communication
+problems.
+.Pp
+.\" These two paragraphs really belong not here but in a midi(9) man page,
+.\" which should one day exist.
+A raw sound generator uses the
+.Sy midisyn
+layer to present a
+.Tn MIDI
+message-driven interface attachable by
+.Nm .
+.Pp
+While
+.Nm
+accepts messages for transmission in any valid mixture of compressed
+or canonical form, they are always presented to an underlying driver
+in the form it prefers.
+Drivers for simple
+.Tn UART Ns -like
+devices
+register their preference for a compressed byte stream, while those like
+.Xr umidi 4 ,
+which uses a packet protocol, or
+.Sy midisyn ,
+which interprets complete
+messages, register for intact canonical messages.
+This design eliminates the
+need for compression and canonicalization logic from all layers above and below
+.Nm
+itself.
+.Sh FILES
+.Bl -tag -width /dev/sequencer -compact
+.It Pa /dev/rmidiN
+.It Pa /dev/music
+.It Pa /dev/sequencer
+.El
+.Sh ERRORS
+In addition to other errors documented for the
+.Xr write 2
+family of system calls,
+.Er EPROTO
+can be returned if the bytes to be written on a raw
+.Nm
+device would violate
+.Tn MIDI
+protocol.
+.Sh SEE ALSO
+.Xr midiplay 1 ,
+.Xr midirecord 1 ,
+.Xr ioctl 2 ,
+.Xr ossaudio 3 ,
+.Xr audio 4 ,
+.Xr mpu 4 ,
+.Xr opl 4 ,
+.Xr umidi 4
+.Pp
+For ports using the ISA bus:
+.Xr cms 4 ,
+.Xr pcppi 4 ,
+.Xr sb 4
+.Pp
+For ports using the PCI bus:
+.Xr autri 4 ,
+.Xr clcs 4 ,
+.Xr eap 4
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Nx 1.4 .
+It was overhauled and this manual page rewritten for
+.Nx 4.0 .
+.Sh BUGS
+Some
+.Tn OSS
+sequencer events and
+.Xr ioctl 2
+operations are unimplemented, as
+.In sys/midiio.h
+notes.
+.Pp
+.Tn OSS
+source-compatible sequencer macros should be added to
+.In sys/soundcard.h ,
+implemented with the
+.Nx
+ones in
+.In sys/midiio.h ,
+so sources written for OSS can be easily compiled.
+.Pp
+The sequencer blocks (or returns
+.Er 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.
+.Pp
+.Dv FIOASYNC
+enables signal delivery to the calling process only;
+.Dv FIOSETOWN
+is not supported.
+.Pp
+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.
+.Pp
+The
+.Dv SEQUENCER_TMR_TIMEBASE
+.Xr ioctl 2
+will report successfully setting any
+timebase up to ridiculously high resolutions, though the actual
+resolution, and therefore jitter, is constrained by
+.Xr hz 9 .
+Comparable sequencer implementations typically allow a selection from available
+sources of time interrupts that may be programmable.
+.Pp
+The device number in a sequencer event is treated on
+.Xr write 2
+as index into
+the array of
+.Tn MIDI
+devices the sequencer has opened, but on
+.Xr read 2
+as the
+unit number of the source
+.Tn MIDI
+device; these are usually the same if the
+sequencer has opened all the
+.Tn MIDI
+devices (that is, none was already open
+at its raw node when the sequencer was opened), but might not be the same
+otherwise.
+.Pp
+There is at present no way to make reception nonpromiscuous,
+should anyone have a reason to want to.
+.Pp
+There should be ways to override default Active Sense behavior.
+As one obvious
+case, if an application is seen to send Active Sense explicitly,
+.Nm
+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
+.Dv EOF .
+.Pp
+When a
+.Nm
+stream is open by the sequencer, Active Sense messages received on the stream
+are passed to the sequencer and not interpreted by
+.Nm .
+The sequencer at present neither does anything itself with Active Sense
+messages received, nor supports the
+.Tn OSS
+.Tn API
+for making them available to the user process.
+.Pp
+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.
+.Pp
+.Sy midisyn
+is too rudimentary at present to get satisfactory results from any
+onboard synth.
+It lacks the required special interpretation of the
+General
+.Tn MIDI
+percussion channel in GM mode.
+More devices should be supported; some sound cards with synthesis
+capability have
+.Nx
+drivers that implement the
+.Xr audio 4
+but not the
+.Sy midisyn
+interface.
+Voice stealing algorithm does not follow the General
+.Tn MIDI
+Developer Guidelines.
+.Pp
+.Tn 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
+.Xr hardclock 9
+itself.
+Similar functionality will be in OSS4; with the right infrastructure
+it should be possible to support both.
+When merging
+.Tn MIDI
+streams, a notion of transaction
+is needed to group critical message sequences.
+If
+.Tn ALSA
+or
+.Tn OSS4
+have no such notion, it should be provided as an upward-compatible
+extension.
+.Pp
+I would rather have
+.Xr open 2
+itself return an error (by the POSIX description
+.Er ENODEV
+looks most appropriate) if a read or write mode
+is requested that is not supported by the instance, rather than letting
+.Xr open 2
+succeed and
+.Xr read 2
+or
+.Xr write 2
+return \-1, but so help me, the latter seems
+the more common
+.Ux
+practice.