diff options
| author | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 15:32:58 -0400 |
|---|---|---|
| committer | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 15:32:58 -0400 |
| commit | 5cb84ec742fd33f78c8022863fadaa8d0d93e176 (patch) | |
| tree | 1a81ca3665e6153923e40db7b0d988f8573ab59c /static/netbsd/man4/midi.4 | |
| parent | a59214f344567c037d5776879bcfc5fcc1d4d5f6 (diff) | |
feat: Added NetBSD man pages
Diffstat (limited to 'static/netbsd/man4/midi.4')
| -rw-r--r-- | static/netbsd/man4/midi.4 | 771 |
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. |
