Chapter 9: CD Audio Playback

OVERVIEW
If your game is going to end up on CD, congratulations—you have the easiest and most versatile approach to implementing game music. Unless you're packing that disc to the gills (and can spare no space for uncompressed audio), or you need music that changes at runtime, you'll want to use CD audio for your game's music.This chapter is going to concentrate on the creation of a CCDPlayer class. Here's the class declaration, taken from

class CCDPlayer
{
public:
CCDPlayer();
virtual ~CCDPlayer();
void Init(HWND hwnd, char driveletter = 0);
void UnInit();
void Play(int track);
bool IsPlaying();
bool IsPaused();
void Stop();
void Pause();
void Resume();
void OpenCDDoor();
void CloseCDDoor();
bool IsCDInDrive();
CTrackMinSecFrame GetCurrentPos();
int GetTrackLength(int track);
int GetNumTracks();
static std::vector<CCDDeviceInfo> GetAvailableDevices();
protected:
bool m_InitGood;
bool m_Paused;
CTrackMinSecFrame m_PausedPos;
static void HandleError(MCIERROR err);
HWND m_hWnd;
DWORD m_DeviceID;
};
As you can see, this is a no-frills CD player—there are no methods for seeking within a track or probing the specific capabilities of a CD drive. This class only knows the simple stuff—everything a game would need, and nothing more.Notice that this class relies on a couple of other classes—CTrackMinSecFrame, and CCDDeviceInfo. Both of these are really just collections of public variables. CTrackMinSecFrame contains four integers—m_Track, m_Minute, m_Second, and m_Frame, which together define a specific time position in a CD. CCDDeviceInfo contains a few strings that describe a given CD audio drive. The drive letter is stored here (m_DriveLetter), alongside a short description of the drive (m_Description) and the UPC code (m_CDProductCode) and CD ID (m_CDID) of the CD in the drive, if any. All of these tidbits of data come from Windows, and you'll learn more about them in a few sections.Now, here's how to flesh out that class declaration using the MCI.