The Entry Point for MIDI Output Drivers

A MIDI output driver must have an entry-point function named modMessage to process messages sent by MMSYSTEM.

Synchronous Versus Asynchronous Message Processing

MIDI output device drivers can process the MODM_DATA and MODM_LONGDATA messages either synchronously or asynchronously. If a driver processes these messages synchronously, it waits until all the data has been sent to the hardware before returning from the modMessage function. An asynchronous driver puts the data in a queue and returns immediately. The data is then sent to the hardware in the background.

Whether a driver is written to be synchronous or asynchronous usually depends on the hardware being supported. An asynchronous driver is desirable because it lets foreground applications run while it processes data; however, some hardware may not support asynchronous data transfer. The Sound Blaster sample driver processes the MODM_DATA and MODM_LONGDATA messages synchronously.

Interrupt-Time and Reentrancy Considerations for modMessage

The midiOutShortMsg and midiOutLongMsg functions can be called by applications (and by device drivers) at interrupt time. Thus, the modMessage entry-point function in a MIDI output device driver can be accessed at interrupt time and must be written to be reentrant for the MODM_DATA and MODM_LONGDATA messages.

Note

For internal MIDI synthesizer drivers, the interrupt-time reception of the MODM_DATA and MODM_LONGDATA messages has an additional consequence: The driver cannot access the disk at interrupt-time to load patch data if it receives a MIDI program-change request.

An example of the reentrancy situation is illustrated by an application that takes incoming MIDI events and sends them to a MIDI output port. The application's low-level callback function for MIDI input receives a MIDM_DATA message, accompanied by the incoming MIDI data. The callback function calls midiOutShortMsg to send the data to a MIDI output port. The modMessage entry-point function in the output port driver is called with a MODM_DATA message. This all happens at interrupt time. While modMessage is processing the MODM_DATA message, another MIDI event arrives at the input port, and the process starts again, with modMessage being reentered with another MODM_DATA message.

To handle being called at interrupt time, the modMessage entry-point function must follow these guidelines:

One way for synchronous drivers to be reentrant is to detect when modMessage is reentered and return a MIDIERR_NOTREADY error.

Note

A good way for a synchronous driver to handle being reentered is for the driver to maintain a small buffer to hold data received when it's reentered, instead of returning MIDIERR_NOTREADY. Before the driver returns from the original modMessage call (the one that was reentered), it makes sure that all data in this buffer is sent to the hardware.