Open Sound System |
Do you have problems with sound/audio application development? Don't panic! Click here for help! |
Under construction.
The MIDI programming section of this manual is currently under construction because there is no MIDI support in OSS 4.0. This section will be completed after MIDI support becomes available.
There are two noticeable changes since earlier OSS versions. The first one is the MTC input mode (SNDCTL_MIDI_MTCINPUT). The second addition is the loopback MIDI device that permits implementing applications such as user space MIDI synthesizers easily. The loopback devices don't actually differ from the ordinary "physical" MIDI ports in any way so there is nothing special in using them. However real time software synthesizers may need to use the MTC input timing mode to avoid timing jitter in the audio output.
The third change in OSS 4.0 is that the development of the previous sequencer (/dev/sequencer and /dev/music) API has been halted. Instead the same functionality will be provided based on the MIDI "port" interface. The main reason is that the sequencer approach resulted in a huge number of different messages that were already defined in the MIDI specifications. This prevented applications from using new MIDI features before the sequencer API was updated. Another reason is that the MIDI port interface is extremely simple and well defined approach.
To make it possible to implement user land software synthesizer applications we have added a new "MIDI loopback" device driver to OSS. We have created a very simple sample program (softsynth.c) that demonstrates how simple and robust this new MIDI interface is.
MIDI is a serial communication protocol developed for communication between musical instruments. It's defined in the specifications published by MIDI Manufactur's Assiciation (MMA). To get the specifications you can order them for example using MMA's web site . Some unofficial information is available from the internet for free.
This document doesn't explain the MIDI protocol because that information is available elsewhere.
The MIDI port devices of OSS work like serial ports. The application that wants to use MIDI simply opens the MIDI device file using the open system call. After that it simply writes MIDI bytes to the device and they will be sent out from the physical device as quickly as possible. If data is written faster than the MIDI line can transfer then the bytes will be buffered by the OSS driver until they can be transmitted. Recording MIDI data works in the identical way.
The MIDI ports are often called as MPU-401 or UART-401 devices because Roland MPU-401 was the most common MIDI port device long time ago. OSS supports UART-401 (MPU-401 "UART MODE") compatible devices as well as many other native MIDI interfaces of various sound cards.
There may be several MIDI devices in the system. The available devices are numbered between 0 and N. The /dev/midi00
device file matches the first MIDI port (number 0). /dev/midi01
is the second and so on. The /dev/midi
device file is the "default" MIDI device that can be assigned by the user to point any of the available devices.
There are actually several kinds of MIDI devices.
The way how the particular MIDI port works doesn't matter since all cases will look like the same to the applications. Only the applications working as real-time software synthesizers may need to behave in slightly different way than "ordinary" MIDI applications.
There are two kinds of MIDI related device files available in OSS.
There are several ways how /dev/midi could be bound to the /dev/midiNN devices. Some implementations of OSS may simply connect to the first available device. Other implementations may have sophisticated MIDI patch bay systems. All the details have been intentionally hidden from the applications.
When using the /dev/midi device the application should open the device when it starts and then keep it opened until the program terminates. This makes it easier to route MIDI data between devices and applications. If necessary the application can open several instances of /dev/midi. In such case each of them will be bound to a different MIDI port.
Remember to use the right access mode (O_RDONLY, O_WRONLY or O_RDWR) when opening the MIDI device. Using O_RDWR unnecessarily may prevent some other applications from accessing the same device in different mode. With /dev/midi the access mode determines which devices can be bound to the application. Applications requesting input/output access cannot be bound to a device that can not do both input and output. It's recommended to open two instances of /dev/midi with O_RDONLY and O_WRONLY instead of opening /dev/midi once with O_RDWR.
The MIDI interface can be used in two different modes. In the traditional mode (default) the device behaves much like a tty serial port. The timed mode interface permits sophisticated features such as precise timing based on internal or external timing sources.
The midi.c sample program explains how MIDI output can be used in applications. With the current OSS version the application needs to take care of the timing itself by using usleep()
or some other system services. However in the near future the OSS driver will support timing handled at the driver level.
The midiin.c program is another example of MIDI program that does input.
Things will get bit more difficult if the application does both input and output at the same time or if it needs to handle video, audio or keyboard input too. However handling this kind of issues is very trivial with the select system call.
The timed mode supercedes the /dev/sequencer interface that was used in the earlier OSS versions. It permits the same functionality but in a way that is fully compatible with the official MIDI specifications.
The timed mode and it's features are explained in the Using the timed mode MIDI interface section.
There just very few ioctl calls related with the MIDI interface. In addition the SNDCTL_MIDIINFO call is related with MIDI devices.
Source | Explanation |
midi_timing | Using the timed mode MIDI interface |
SNDCTL_MIDI_EXPRESS_WRITE | Inserts MIDI messages to the beginning of the device output buffer. |
SNDCTL_MIDI_INFO | Get information about a MIDI device (OBSOLETE) |
SNDCTL_MIDI_MPUCMD | Obsolete ioctl call |
SNDCTL_MIDI_MPUMODE | Obsolete ioctl call |
SNDCTL_MIDI_MTCINPUT | Turn on MTC input mode |
SNDCTL_MIDI_PRETIME | Set the pre character wait time. |
SNDCTL_MIDI_SETMODE | Set the interface mode |