BMD
Section: Devices and Network Interfaces (4)
Updated: 08 Jan 1991
Index
Return to Main Contents
NAME
bmd - Berkeley MIDI Driver
SYNOPSIS
pseudo-device bmd 2 init bmdattach
DESCRIPTION
The MIDI driver is a pseudo-device that provides a specialized interface
to a MIDI device connected to a serial line. MIDI messages are read from
and written to the chracter special device files
/dev/midi0,
/dev/midi1,
etc. Once such a file is opened, it must be attached to a MIDI port,
via the BMDATTACH ioctl. No operations (other than close) are allowed on
the file until it has been attached.
Note that a given MIDI device can only be opened by one process at a time,
but a single port can be shared by many files.
If a file is already in use, open will return EBUSY.
Messages are timestamped to make real time processing possible.
Unwanted messages can be filtered out by command type.
MIDI messages are read and written using the following C date structure:
struct midi_msg {
u_long mm_time;
u_char mm_data[4];
#define mm_cmd mm_data[0]
};
mm_time
is a timestamp in MIDI ticks, and
mm_data
is the message. The message length is implicit in the
command byte, which always must be present as the first byte in
the message. The leftover bytes are ignored.
Note that the driver will eliminate redundant status bytes
(and occasionally resend the status so MIDI cables can be moved,
devices powered up, etc. without resetting the device).
Multiple messages can be read or written in a single system call.
System exclusives are handled by extending the mm_data field beyond
the end of the structure. The end of the message is indicated by
the eox MIDI status byte (0xf7), and the next message must begin
at an aligned offset, computed using the BMDALIGN macro.
Messages are limited in length to BMD_MAXMSGLEN bytes. Naturally,
this limitation only applies to system exclusives since all other message
types are shorter than this. Inbound system exclusives longer than this
length will be truncated, and the trailing eox omitted. In the case of
non-truncated messages, an eox byte will always be present
(even if the external device doesn't send one),
so it's possible to determine if a message has been truncated.
A maximum message length is a nuisance but a reasonable implementation
tradeoff. Since very long sysex messages impose delays that preclude
real-time performance, there is no motivation to support them in BMD.
Applications that require large sysexs (i.e., patch dumps) should
simply use the raw interface (i.e. /dev/ttya).
In the presence of mutiple independent writers, MIDI message boundaries
are maintained so the mixed output stream will be uncorrupted.
Each writer has its own independent time base, with time starting
at zero when the port is attached, and counting up at each MIDI clock
tick. Time can be independently reset to an arbitrary value,
but all writers must share the same clock rate.
IOCTL CALLS
The
ioctl
command codes below are defined in <sundev/midi.h>. All commands
require these includes:
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sundev/midi.h>
In addition to FIONREAD, FIONBIO, and FIOASYNC, (see fcntl(2)) the
following commands may be applied to any open MIDI device.
The (third) argument to the
ioctl
should be a pointer to the type indicated.
- BMDATTACH (u_int)
-
Attach a file to a MIDI port (i.e., on a sparc, the argument should be
0 for serial port A and and 1 for B). This must be done before anything
other operations.
- BMDGTIME (u_long)
-
Return the current MIDI clock.
- BMDSTIME (u_long)
-
Set the current MIDI clock for this file and flush the kernel buffers.
- BMDFLUSH (void)
-
Flush the kernel buffers. Output already queued to the serial line
is not affected.
- BMDRATE (u_int)
-
Set the MIDI clock rate. The argument is the microsecond interval
at which to increment the MIDI clock. The default rate is 1000, or
one tick per millisecond. The actual rate used, which may be
different from the request due to hardware constraints, is returned.
- BMDECHO (int)
-
Loop back all inbound channel messages (after filtering) on the indicated
MIDI channel. If the argument is not a valid channel (e.g. -1),
echoing is disabled.
- BMDFILTER (u_long)
-
Set an input filter to discard unwanted MIDI messages.
The filter is a bitmask in which the bit number corresponds to the MIDI
command number (i.e, bit 9 corresponds to "note on" messages).
Those commands for which the corresponding bit is
set
will be ignored.
If bit 15 is set, all system messages will be ignored.
If only a particular system message should be discarded, leave bit 15
clear, and set bit 16+x where x is the low nybble of the system command.
MIDIMASK is defined to midi.h to make this easier. For instance,
to discard after touch and active sensing messages, use:
MIDIMASK(0xd0) | MIDIMASK(0xfe).
-
The default filter discards active sensing.
- BMDPAUSE (void)
-
Stop the MIDI clock; output will remain queued in the kernel.
The clock will stay paused until a BMDRESUME ioctl.
If the file is closed while output is paused, the pending data will
be flushed. This call will pause the output of all MIDI device files in
the system.
- BMDRESUME (void)
-
Re-start the MIDI clock.
- BMDNWRITE (u_int)
-
Returns the number of messages
that can be written without blocking, or if in non-blocking mode,
doing a partial write.
This is useful when an application wants to estimate how much
work ahead to use.
- BMDNBUF (u_int)
-
Set the minmum number of messages the kernel will wait for before returning
from read or select. If the value is out of range, the limit is returned
in the argument (and set). The default is one.
- BMDWLO (u_long)
-
Set the low water mark for writes, i.e., the buffer length (in messages)
that will cause a waiting select (or blocked write) to wakeup.
SEE ALSO
fcntl(2)
FILES
/dev/midi0, /dev/midi1, etc.
BUGS
BMD should be a streams module.
Inbound system exclusives that are terminated by a status byte whose
message length is one (i.e. only tune request) will cause
the latter message to be dropped.
Under SunOS, the MIDI driver will preempt the standard serial port driver.
In other words, if you attach a MIDI file to a serial port that is already
in use (i.e., by getty, slip, your kernel debugger etc.), the serial
driver will stop receiving I/O. This is only a problem when you
"accidently" use the wrong port. The BMD open system call should return
EBUSY, but SunOS makes this too difficult.
Index
- NAME
-
- SYNOPSIS
-
- DESCRIPTION
-
- IOCTL CALLS
-
- SEE ALSO
-
- FILES
-
- BUGS
-
This document was created by
man2html,
using the manual pages.
Time: 00:32:14 GMT, January 04, 2023