Playing audio CDs, part 6 - MCI Command playback
Today, we play the actual audio track on the CD using the MCI commands.
HRESULT CMCICommandCDPlayer::PlayTrack(int TrackNumber){ MCIERROR mciError; MCI_SET_PARMS setParms = {0}; MCI_PLAY_PARMS playParms = {0}; // // The track number from the host app is )ORIGIN 0, MCI is )ORIGIN 1, so adjust it. // TrackNumber += 1; if (TrackNumber > (int)_TrackCount) { printf("Track out of range\n"); return E_FAIL; } // Set the MCI time format to track/minute/second/frame. setParms.dwTimeFormat = MCI_FORMAT_TMSF; mciError = mciSendCommand(_MciHandle, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)&setParms); if (mciError != 0) { printf("MCI Error %x determining CD media status\n",mciError); return HRESULT_FROM_WIN32(mciError); } playParms.dwFrom = MCI_MAKE_TMSF(TrackNumber, 0, 0, 0); if (TrackNumber < _TrackCount) { playParms.dwTo = MCI_MAKE_TMSF(TrackNumber+1, 0, 0, 0); } mciError = mciSendCommand(_MciHandle, MCI_PLAY, MCI_FROM | (TrackNumber <_TrackCount ? MCI_TO : 0) | MCI_WAIT, (DWORD_PTR)&playParms); if (mciError != 0) { printf("MCI Error %x playing media\n",mciError); return HRESULT_FROM_WIN32(mciError); } return S_OK;}
Not much different from the previous versions, in fact it's a pretty straightforward transcription of the previous programs. One minor change is that I'm using the MCI_WAIT flag to ask the MCI commands
That allows me to avoid the Sleep() at the end. I could have done the same thing in the string based version by appending the " wait" command to the play command string.
I'm going to skip a couple of days on this series, it'll take a while to get the Digital Audio Extraction version of this problem ready for publication, DAE's sufficiently compilicated that it'll take several articles to fully describe what I'm doing.
Comments
- Anonymous
April 27, 2005
Out of curiosity, why didn't you use the " wait" command in the string based version? Is there a performance and/or security advantage to using a Sleep()? - Anonymous
April 27, 2005
Todd,
Official answer? I did it to show the sync/async versions. There's no real difference between the two (but you really don't want to use the sync version in a Windows app).
Honest answer? I didn't think of it - the WMP version needed a sleep, so I put a sleep into the MCI version :)