⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdplayer.cpp

📁 游戏音频程序设计-Beginning.Game.Audio.Programming
💻 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 + -