📄 cdplayer.cpp
字号:
// CDPlayer.cpp: implementation of the CCDPlayer class.
//
//////////////////////////////////////////////////////////////////////
#include "CDPlayer.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace std;
namespace AudioEngine {
CCDPlayer::CCDPlayer()
{
m_Paused = false;
m_InitGood = false;
m_DeviceID = 0;
}
CCDPlayer::~CCDPlayer()
{
if (m_InitGood) UnInit();
}
void CCDPlayer::Init(HWND hwnd, char driveletter)
{
m_hWnd = hwnd; // save for later
// open device
char drivestring[3] = "C:";
drivestring[0] = driveletter;
MCI_OPEN_PARMS openparms;
ZeroMemory(&openparms, sizeof(MCI_OPEN_PARMS));
openparms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;
openparms.lpstrElementName = drivestring;
MCIERROR e = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID)&openparms);
if (e) HandleError(e);
m_DeviceID = openparms.wDeviceID;
// Set the time format to track/minute/second/frame (TMSF).
MCI_SET_PARMS mciSetParms;
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
e = mciSendCommand(m_DeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms);
if (e) HandleError(e);
m_InitGood = true;
}
void CCDPlayer::HandleError(MCIERROR err)
{
char buf[256];
mciGetErrorString(err, buf, sizeof(buf));
throw(buf);
// TODO
}
void CCDPlayer::UnInit()
{
if (!m_InitGood) return; // nothing to do
// stop anything that might be playing
if (IsPlaying()) Stop();
// close device
MCI_GENERIC_PARMS genericparms;
ZeroMemory(&genericparms, sizeof(MCI_GENERIC_PARMS));
mciSendCommand(m_DeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)(LPVOID)&genericparms);
m_InitGood = false;
}
vector<CCDDeviceInfo> CCDPlayer::GetAvailableDevices()
{
DWORD retvalue=0;
MCIERROR e;
vector<CCDDeviceInfo> devices;
// loop through entire alphabet of drive letters
for (char drive = 'C'; drive <= 'Z'; drive++) {
char buf[256];
char driveletter[3] = "C:";
// see if we can open this drive as a CD audio device
MCI_OPEN_PARMS openparms;
ZeroMemory(&openparms, sizeof(MCI_OPEN_PARMS));
openparms.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;
driveletter[0] = drive;
openparms.lpstrElementName = driveletter;
e = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID)&openparms);
if (!e) {
// success! this must be a drive that can play CD Audio, so ask it some questions
// and add it to our vector.
CCDDeviceInfo devinfo;
devinfo.m_DriveLetter = drive;
int deviceid = openparms.wDeviceID;
// ask device for its description
buf[0] = 0;
MCI_INFO_PARMS infoparms;
ZeroMemory(&infoparms, sizeof(MCI_INFO_PARMS));
infoparms.dwRetSize = sizeof(buf);
infoparms.lpstrReturn = buf;
e = mciSendCommand(deviceid, MCI_INFO, MCI_INFO_PRODUCT, (DWORD)(LPVOID)&infoparms);
devinfo.m_Description = string(buf);
// ask device for the product code of the CD in it
buf[0] = 0;
infoparms.dwRetSize = sizeof(buf);
infoparms.lpstrReturn = buf;
mciSendCommand(deviceid, MCI_INFO, MCI_INFO_MEDIA_UPC, (DWORD)(LPVOID)&infoparms);
devinfo.m_CDProductCode = buf;
// ask device for the ID of the CD in it
buf[0] = 0;
infoparms.dwRetSize = sizeof(buf);
infoparms.lpstrReturn = buf;
mciSendCommand(deviceid, MCI_INFO, MCI_INFO_MEDIA_IDENTITY, (DWORD)(LPVOID)&infoparms);
devinfo.m_CDID = buf;
// close device
MCI_GENERIC_PARMS genericparms;
ZeroMemory(&genericparms, sizeof(MCI_GENERIC_PARMS));
mciSendCommand(deviceid, MCI_CLOSE, MCI_WAIT, (DWORD)(LPVOID)&genericparms);
// add it to the vector
devices.push_back(devinfo);
}
} // next drive letter
return(devices);
}
void CCDPlayer::OpenCDDoor()
{
if (!m_InitGood) return;
m_Paused = false;
mciSendCommand(m_DeviceID,MCI_SET,MCI_SET_DOOR_OPEN,0);
}
void CCDPlayer::CloseCDDoor()
{
if (!m_InitGood) return;
mciSendCommand(m_DeviceID,MCI_SET,MCI_SET_DOOR_CLOSED,0);
}
bool CCDPlayer::IsCDInDrive()
{
if (!m_InitGood) return(false);
MCI_STATUS_PARMS statusparms;
ZeroMemory(&statusparms, sizeof(MCI_STATUS_PARMS));
statusparms.dwItem = MCI_STATUS_MEDIA_PRESENT;
MCIERROR e = mciSendCommand(m_DeviceID,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID)&statusparms);
if (e) HandleError(e);
return(statusparms.dwReturn == TRUE);
}
void CCDPlayer::Play(int track)
{
m_Paused = false;
if (!m_InitGood) return;
MCIERROR e;
MCI_PLAY_PARMS mciPlayParms;
// Begin playback from the given track and play until the beginning
// of the next track. The window procedure function for the parent
// window will be notified with an MM_MCINOTIFY message when
// playback is complete. Unless the play command fails, the window
// procedure closes the device.
mciPlayParms.dwFrom = 0L;
mciPlayParms.dwTo = 0L;
mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
mciPlayParms.dwTo = MCI_MAKE_TMSF(track + 1, 0, 0, 0);
mciPlayParms.dwCallback = (DWORD)m_hWnd;
e = mciSendCommand(m_DeviceID, MCI_PLAY, MCI_FROM | MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
if (e) HandleError(e);
}
void CCDPlayer::Stop()
{
m_Paused = false;
if (!m_InitGood) return;
MCI_GENERIC_PARMS genericparms;
ZeroMemory(&genericparms, sizeof(MCI_GENERIC_PARMS));
genericparms.dwCallback = (DWORD)m_hWnd;
mciSendCommand(m_DeviceID, MCI_STOP, MCI_WAIT, (DWORD)(LPVOID)&genericparms);
}
void CCDPlayer::Pause()
{
if (!m_InitGood) return;
// store current play position
m_PausedPos = GetCurrentPos();
// tell CD to stop
Stop();
// set paused flag
m_Paused = true;
}
void CCDPlayer::Resume()
{
if (!m_InitGood) return;
if (!m_Paused) return;
// play from pause position to end of track
MCIERROR e;
MCI_PLAY_PARMS mciPlayParms;
// Begin playback from the given track and play until the beginning
// of the next track. The window procedure function for the parent
// window will be notified with an MM_MCINOTIFY message when
// playback is complete. Unless the play command fails, the window
// procedure closes the device.
mciPlayParms.dwFrom = 0L;
mciPlayParms.dwTo = 0L;
mciPlayParms.dwFrom = m_PausedPos;
mciPlayParms.dwTo = MCI_MAKE_TMSF(m_PausedPos.m_Track + 1, 0, 0, 0);
mciPlayParms.dwCallback = (DWORD)m_hWnd;
e = mciSendCommand(m_DeviceID, MCI_PLAY, MCI_FROM | MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
if (e) HandleError(e);
m_Paused = false;
}
CTrackMinSecFrame CCDPlayer::GetCurrentPos()
{
CTrackMinSecFrame pos;
if (!m_InitGood) return(pos);
if (m_Paused) return(m_PausedPos);
if (!IsPlaying()) return(pos);
MCI_STATUS_PARMS statusparms;
ZeroMemory(&statusparms, sizeof(MCI_STATUS_PARMS));
statusparms.dwItem = MCI_STATUS_POSITION;
MCIERROR e = mciSendCommand(m_DeviceID,MCI_STATUS,MCI_STATUS_ITEM | MCI_WAIT,(DWORD)(LPVOID)&statusparms);
if (e) HandleError(e);
pos = statusparms.dwReturn;
return(pos);
}
int CCDPlayer::GetNumTracks()
{
if (!m_InitGood) return(false);
MCI_STATUS_PARMS statusparms;
ZeroMemory(&statusparms, sizeof(MCI_STATUS_PARMS));
statusparms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
MCIERROR e = mciSendCommand(m_DeviceID,MCI_STATUS,MCI_STATUS_ITEM | MCI_WAIT,(DWORD)(LPVOID)&statusparms);
if (e) HandleError(e);
return(statusparms.dwReturn);
}
bool CCDPlayer::IsPlaying()
{
if (!m_InitGood) return(false);
MCI_STATUS_PARMS statusparms;
ZeroMemory(&statusparms, sizeof(MCI_STATUS_PARMS));
statusparms.dwItem = MCI_STATUS_MODE;
MCIERROR e = mciSendCommand(m_DeviceID,MCI_STATUS,MCI_STATUS_ITEM | MCI_WAIT,(DWORD)(LPVOID)&statusparms);
if (e) HandleError(e);
return(statusparms.dwReturn == MCI_MODE_PLAY);
}
bool CCDPlayer::IsPaused()
{
return(m_Paused);
}
} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -