79.3.9 Getting Information About Devices and Media

Use the MCI_STATUS command along with the MCI_STATUS_PARMS parameter block to get information about the status of an open device and its associated device element. MMSYSTEM.H defines the MCI_STATUS_PARMS parameter block as follows:

typedef struct {

DWORD dwCallback; /* callback for MCI_NOTIFY flag */

DWORD dwReturn; /* status information is returned here */

DWORD dwItem; /* identifies status item */

DWORD dwTrack; /* track number */

} MCI_STATUS_PARMS;

Before using the MCI_STATUS command, you must identify the status item to query for by putting a constant in the dwItem field of the parameter block. The following list shows different status items you can query for and the corresponding constant for each item for different types of audio devices:

All Audio Devices

Constant Status Item

MCI_STATUS_LENGTH Length of the media
MCI_STATUS_POSITION Current position
MCI_STATUS_MODE Current mode
MCI_STATUS_TIME_FORMAT Time format
MCI_STATUS_READY Ready state

Waveform Devices

Constant Status Item

MCI_WAVE_STATUS_BLOCKALIGN  
  Block alignment
MCI_WAVE_STATUS_FORMATTAG  
  Format tag
MCI_WAVE_STATUS_CHANNELS  
  Number of channels
MCI_WAVE_STATUS_SAMPLESPERSEC  
  Sample rate
MCI_WAVE_STATUS_AVGBYTESPERSEC  
  Average bytes per second
MCI_WAVE_STATUS_BITSPERSAMPLE  
  Bits per sample (in PCM format files)
MCI_WAVE_STATUS_LEVEL  
  Record level

Compact Disc Devices

Constant Status Item

MCI_STATUS_NUMBER_OF_TRACKS Number of tracks
MCI_STATUS_MEDIA_PRESENT Media present
MCI_STATUS_CURRENT_TRACK Current track

MIDI Sequencer Devices

CI_SEQ_STATUS_TEMPO Tempo
CI_SEQ_STATUS_PORT Port
MCI_SEQ_STATUS_OFFSET SMPTE offset
MCI_SEQ_STATUS_DIVTYPE Division type of file

79.3.9.1 Getting Track-Relative Information for Compact Disc Devices

For compact disc devices, you can get the starting position and length of a track by specifying the MCI_TRACK flag and setting the dwTrack field of MCI_STATUS_PARMS to the desired track number. To get the starting position of a track, set the dwItem field to MCI_STATUS_POSITION. To get the length of a track, set dwItem to MCI_STATUS_LENGTH. For example, the following function gets the total number of tracks on the disc and the starting position of each track. It then uses the MessageBox function to report the starting positions of the tracks.

/* Uses the MCI_STATUS command to get and display the starting times

* for the tracks on a compact disc. Returns 0L on success; otherwise,

* it returns an MCI error code.

*/

DWORD getCDTrackStartTimes(void)

{

UINT wDeviceID;

int i, iNumTracks;

DWORD dwReturn;

DWORD dwPosition;

DWORD *pMem;

char szTempString[64];

char szTimeString[512] = "\0"; // big enough for 20 tracks

MCI_OPEN_PARMS mciOpenParms;

MCI_SET_PARMS mciSetParms;

MCI_STATUS_PARMS mciStatusParms;

/* Open the compact disc device by specifying the device name.

*/

mciOpenParms.lpstrDeviceType = "cdaudio";

if (dwReturn = mciSendCommand(NULL, MCI_OPEN,

MCI_OPEN_TYPE,

(DWORD)(LPVOID) &mciOpenParms))

{

/* Failed to open device; don't have to close it, just return error.

*/

return (dwReturn);

}

/* Device opened successfully, get the device ID.

*/

wDeviceID = mciOpenParms.wDeviceID;

/* Set the time format to minute/second/frame format.

*/

mciSetParms.dwTimeFormat = MCI_FORMAT_MSF;

if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT,

(DWORD)(LPVOID) &mciSetParms))

{

mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

return (dwReturn);

}

/* Get the number of tracks; limit to number we can display (20).

*/

mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;

if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM,

(DWORD)(LPVOID) &mciStatusParms))

{

mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

return (dwReturn);

}

iNumTracks = mciStatusParms.dwReturn;

iNumTracks = min(iNumTracks, 20);

/* Allocate memory to hold starting positions.

*/

pMem = (DWORD *)LocalAlloc(LPTR, iNumTracks * sizeof(DWORD));

if (pMem == NULL)

{

mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

return (-1);

}

/* For each track, get and save the starting position and

* build a string containing starting positions.

*/

for(i=1; i<=iNumTracks; i++)

{

mciStatusParms.dwItem = MCI_STATUS_POSITION;

mciStatusParms.dwTrack = i;

if (dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,

MCI_STATUS_ITEM | MCI_TRACK,

(DWORD)(LPVOID) &mciStatusParms))

{

mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);

return (dwReturn);

}

pMem[i-1] = mciStatusParms.dwReturn;

wsprintf(szTempString, "Track %2d - %02d:%02d:%02d\n",

i,

MCI_MSF_MINUTE(pMem[i-1]),

MCI_MSF_SECOND(pMem[i-1]),

MCI_MSF_FRAME(pMem[i-1]));

lstrcat(szTimeString, szTempString);

}

/* Use MessageBox to display starting times.

*/

MessageBox(hMainWnd, szTimeString, "Track Starting Position",

MB_ICONINFORMATION);

/* Free memory and close the device.

*/

LocalFree((HANDLE) pMem);

if (dwReturn = mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL))

{

return (dwReturn);

}

return (0L);

}