Applications that access memory buffers to store and access MIDI data can use the memory I/O features of the multimedia input/output (MMIO) file services. This technique consists of opening a memory file using mmioOpen. mmioOpen has a pointer to the buffer of MIDI data as a parameter. This buffer can then be operated on by MCI and MMIO as if it were a file.
The details of opening the file and setting up the MIDI buffer varies depending on an application's requirements. For example, the memory buffer can be allocated by the MMIO system and filled subsequently by the application, or the memory buffer can be allocated by the application and passed to MMIO. The buffer can be filled in different ways such as mmioRead, mmioWrite, and mmioAdvance.
Care must be taken when calling MMIO functions and sending MCI messages to the same memory file. MMIO and MCI are independent subsystems linked only through the MMIO memory handle passed to MCI_OPEN. There is for example, no relationship between MCI_SEEK and mmioSeek. Each subsystem keeps its own set of relevant files and stream pointers. If one subsystem changes the data in memory, but the memory had previously been cued with MCI_CUE, the change of data will not be recognized by MCI until a call to reload the streams has been issued.
The following code fragment shows the opening of a memory file with a user-supplied MIDI buffer of untranslated (format 0 or 1) data and the playing of that data through MCI.
{ /* variable for IOProc */ PMMIOPROC pIOProc; HMODULE hModMidiio; /* variables for memory file */ MMIOINFO mmioInfo; CHAR UserBuffer[SIZE_OF_BUFFER]; HMMIO hmmio; /* variables for MCI commands */ MCI_OPEN_PARMS mop; MCI_PLAY_PARMS mpp; /* Open memory file. Provide MIDI-filled data buffer to MMIO, so * data buffer becomes file image in memory. Also specify that * the data will need to be translated. */ mmioInfo.pchBuffer = UserBuffer; /* Filled with untranslated MIDI data */ mmioInfo.cchBuffer = SIZE_OF_BUFFER; /* User-defined */ mmioInfo.ulTranslate = MMIO_TRANSLATEDATA | MMIO_TRANSLATEHEADER; /* Need to translate data */ mmioInfo.fccIOProc = mmioFOURCC( 'M', 'I', 'D', 'I');/* Data format */ mmioMemInfo.fccChildIOProc = FOURCC_MEM; /* Storage type */ hmmio = mmioOpen ( NULL, mmioInfo, MMIO_READWRITE ); /* open MIDI device */ mop.pszElementName = (PSZ) hmmiomem; mciSendCommand( 0, /* We don't know the device yet. */ MCI_OPEN, /* MCI message */ MCI_WAIT | MCI_OPEN_MMIO | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE (ULONG) &mop, /* Parameters for the message */ 0 ); /* Parameter for notify message */ /* play MIDI memory file for 1 second */ mpp.ulFrom=0; mpp.ulTo=3000; /* default is MMTIME units (1/3000 second) */ mciSendCommand( mop.usDeviceID, /* Device to play the data */ MCI_PLAY, /* MCI message */ MCI_WAIT | MCI_FROM | MCI_TO, /* Flags for the MCI message */ (ULONG) &mpp, /* Parameters for the message */ 0 ); /* No parm necessary */ /* close device */ mciSendCommand( mop.usDeviceID, /* Device to play this */ MCI_CLOSE, /* MCI message */ MCI_WAIT, /* Flags for the MCI message */ (ULONG) NULL, /* Parameters for the message */ (ULONG) NULL ); /* Parameter for notify message */ }