Before proceeding, you should now read MCI Devices. This article gives necessary background information about the MCI API.
If you're using mciSendString(), you literally include "type sequencer" as part of the command string to indicate that you're opening the Sequencer device.
You can also specify an alias. This is just a string name that you use to identify the open device. Think of it as a string version of a device handle. After all, the string interface doesn't return binary values, so it can't return a handle. Instead it allows you to pick out a name, which you'll use with other commands you issue, in lieu of having a handle.
Here then is an example of opening the Sequencer device using the Command String interface. The MIDI file that we ask it to open is named C:\WINDOWS\SONG.MID. The alias we give this instance of the Sequencer is A_Song. (ie, Whenever we subsequently use A_Song as the device name with other commands, we'll be performing operations on the C:\WINDOWS\SONG.MID file).
TCHAR buf[128]; DWORD err; /* Open a Sequencer device associated with the C:\WINDOWS\SONG.MID file */ if ((err = mciSendString("open C:\\WINDOWS\\SONG.MID type sequencer alias A_Song", 0, 0, 0))) { /* Error */ printf("Sequencer device did not open!\r\n"); if (mciGetErrorString(err, &buf[0], sizeof(buf))) printf("%s\r\n", &buf[0]); }
If you're using mciSendCommand(), then you need to initialize and pass a MCI_OPEN_PARMS structure. You set the lpstrDeviceType field of this structure to MCI_DEVTYPE_SEQUENCER. You also must pass mciSendCommand() the MCI_OPEN_TYPE and MCI_OPEN_TYPE_ID flags to indicate that you've set the lpstrDeviceType field to a predefined constant (MCI_DEVTYPE_SEQUENCER).
If playing back a MIDI file, then you also need to specify the name of the MIDI file to open by setting the lpstrElementName field to point to the name of the desired file. You also must pass mciSendCommand() the MCI_OPEN_ELEMENT flag to indicate that you've set the lpstrElementName field. The Sequencer device does not support recording MIDI.
The second arg will be MCI_OPEN to indicate an open command.
Here then is an example of opening the Sequencer device using the Command Message interface.
DWORD err; MCI_OPEN_PARMS midiParams; TCHAR buffer[128]; /* Open a Sequencer device associated with the C:\WINDOWS\SONG.MID file */ midiParams.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_SEQUENCER; midiParams.lpstrElementName = "C:\\WINDOWS\\SONG.MID"; if ((err = mciSendCommand(0, MCI_OPEN, MCI_WAIT|MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID, (DWORD)(LPVOID)&midiParams))) { /* Error */ printf("ERROR: Sequencer device did not open!\r\n"); if (mciGetErrorString(err, &buffer[0], sizeof(buffer))) printf("%s\r\n", &buffer[0]); } else { /* The device opened successfully. midiParams.wDeviceID now contains the device ID */ }
If you're using mciSendCommand(), then you need to initialize and pass a MCI_PLAY_PARMS structure. (Actually, unless you use the MCI_NOTIFY, MCI_FROM, and/or MCI_TO flags, there is no initialization required). If you want to play only part of the MIDI file, then you can set the dwFrom and/or dwTo fields to the start and end positions respectively, and pass the MCI_FROM and/or MCI_TO flags respectively. The dwFrom and dwTo fields are normally expressed in terms of PPQN clocks. But you can utilize other means of expressing this offset, for example in terms of milliseconds, by first issuing an MCI_SET command (with the MCI_SET_TIME_FORMAT flag, and your desired choice of how to express such offsets).
The second arg will be MCI_PLAY to indicate a play command.
The first arg will be the device ID that you obtained when you opened the device.
Here then is an example of playing a MIDI file on the Sequencer device using the Command Message interface.
DWORD err; MCI_PLAY_PARMS playParams; TCHAR buffer[128]; /* Play a Sequencer device. Assume that midiParams.wDeviceID was set according to our open example above */ if ((err = mciSendCommand(midiParams.wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)(LPVOID)&playParams))) { /* Error */ printf("ERROR: Midi did not play!\r\n"); if (mciGetErrorString(err, &buffer[0], sizeof(buffer))) printf("%s\r\n", &buffer[0]); } else { /* The midi song has played from beginning to end */ }You can download my Message Midi Play C example to show how to play a MIDI file using the Command Message interface. Included are the Project Workspace files for Visual C++ 4.0, but since it is a console app, any Windows C compiler should be able to compile it. Remember that all apps should include MMSYSTEM.H and link with WINMM.LIB (or MMSYSTEM.LIB if Win3.1). This is a ZIP archive. Use an unzip utility that supports long filenames.
If you're using mciSendCommand(), then you need to initialize and pass a MCI_GENERIC_PARMS structure. (Note that this structure is a subset of all of the other MCI structures that you pass to mciSendCommand(). In other words, you can substitute any of the other MCI structures for this one). Unless you use the MCI_NOTIFY flag, there is actually no initialization required.
The second arg will be MCI_CLOSE to indicate a close command.
The first arg will be the device ID that you obtained when you opened the device.
Here then is an example of closing the Sequencer device using the Command Message interface.
/* Close the Sequencer device. Assume that midiParams.wDeviceID was set according to our open example above */ mciSendCommand(midiParams.wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)(LPVOID)&midiParams);