emidi.cpp
来自「《突破Visual C++.NET编程实例五十讲+源文件,初学者学习的好东东!」· C++ 代码 · 共 279 行
CPP
279 行
// Midi.cpp: CExMidi类的实现赛文件.
//
#include "stdafx.h"
#include "emidi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//构造/销毁
CExMidi::CExMidi()
{
// 初始化成员变量
m_Open = FALSE;
m_Pause = FALSE;
m_Playing = FALSE;
m_wDeviceID = 0;
}
CExMidi::~CExMidi()
{
Close ();
}
int CExMidi::GetDevices ()
{
return (int) midiOutGetNumDevs ();
}
DWORD CExMidi::Open ()
{
DWORD Dflag;
if (!m_Open)
{
// 初始化成员变量
m_Open = m_Pause = m_Playing = FALSE;
m_wDeviceID = 0;
// 文件是否存在
CFileStatus Status;
if (!CFile::GetStatus (m_name, Status))
return FALSE;
// 打开设备
MCI_OPEN_PARMS OpenP;
OpenP.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_SEQUENCER;
OpenP.lpstrElementName = (LPCSTR) m_name;
OpenP.wDeviceID = 0;
Dflag = mciSendCommand (NULL, MCI_OPEN, MCI_WAIT | MCI_OPEN_TYPE |
MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &OpenP);
if(Dflag)
return Dflag;
m_wDeviceID = OpenP.wDeviceID;
m_Open = TRUE;
// 将时间格式设为tmsf格式
MCI_SET_PARMS SetP;
SetP.dwTimeFormat = MCI_FORMAT_MILLISECONDS ;//注意只有这种格式可以播放
Dflag = mciSendCommand (m_wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID) &SetP);
if(Dflag)
{
Close ();
return Dflag;
}
mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL);
}
return NULL;
}
DWORD CExMidi::Close ()
{
DWORD Dflag;
if (m_Open)
{ // 停止播放关闭设备
if (m_Playing || m_Pause)
mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);
Dflag = mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL);
if(Dflag)return Dflag;
// 清空成员变量
m_Open = m_Pause = m_Playing = FALSE;
m_wDeviceID = 0;
}
return NULL;
}
DWORD CExMidi::Play ()
{
DWORD Dflag;
if (m_Open)
{
MCI_PLAY_PARMS PlayP;
PlayP.dwCallback = NULL;
PlayP.dwFrom = ((GetMinutes () * 60) + GetSeconds ()) * 1000;
Dflag = mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM, (DWORD)(LPVOID) &PlayP);
return Dflag;
m_Pause = FALSE;
m_Playing = TRUE;
return NULL;
}
return NULL;
}
void CExMidi::Stop ()
{
if (m_Open && m_Playing)
{
mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);
mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL);
m_Playing = FALSE;
m_Pause = FALSE;
}
}
DWORD CExMidi::Pause( )
{
DWORD Dflag;
if (m_Open && m_Playing)
{
MCI_PLAY_PARMS PlayP;
Dflag = mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &PlayP);
if(Dflag)
return Dflag;
m_Pause = TRUE;
}
return NULL;
}
DWORD CExMidi::GetMidiLength (int *pnMinutes, int *pnSeconds)
{
DWORD Dflag;
if (m_Open)
{
MCI_STATUS_PARMS StatusP;
StatusP.dwItem = MCI_STATUS_LENGTH;
Dflag= mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP);
if(Dflag)
{
*pnMinutes = -1;
*pnSeconds = -1;
return Dflag;
}
*pnMinutes = (StatusP.dwReturn / 1000) / 60;
*pnSeconds = (StatusP.dwReturn / 1000) % 60;
return NULL;
}
*pnMinutes = -1;
*pnSeconds = -1;
return NULL;
}
int CExMidi::GetMinutes ()
{
if (m_Open)
{
MCI_STATUS_PARMS StatusP;
StatusP.dwItem = MCI_STATUS_POSITION;
if (mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP))
return -1;
return (int) ((StatusP.dwReturn / 1000) / 60);
}
return -1;
}
int CExMidi::GetSeconds ()
{
if (m_Open)
{
MCI_STATUS_PARMS StatusP;
StatusP.dwItem = MCI_STATUS_POSITION;
if (mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP))
return -1;
return (int) ((StatusP.dwReturn / 1000) % 60);
}
return -1;
}
BOOL CExMidi::IsPlaying ()
{
if (m_Open)
{
MCI_STATUS_PARMS StatusP;
StatusP.dwItem = MCI_STATUS_MODE;
if (mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT
| MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP))
return FALSE;
if (StatusP.dwReturn == MCI_MODE_PLAY)
{
m_Playing = TRUE;
m_Pause = FALSE;
return TRUE;
}
else if (StatusP.dwReturn == MCI_MODE_PAUSE)
{
m_Playing = TRUE;
m_Pause = FALSE;
return TRUE;
}
else
{
m_Playing = FALSE;
m_Pause = FALSE;
return FALSE;
}
}
return FALSE;
}
DWORD CExMidi::SeekTo (int nMinute, int nSecond)
{
DWORD Dflag;
if (m_Open)
{
MCI_SEEK_PARMS SeekP;
SeekP.dwTo = (nMinute * 60 + nSecond) * 1000;
if (m_Playing && !m_Pause)
mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);
Dflag = mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &SeekP);
if(Dflag)
return Dflag;
if (m_Playing && !m_Pause)
{
Dflag = Play ();
if(Dflag)return Dflag;
}
return NULL;
}
return NULL;
}
void CExMidi::Forward (int nSeconds)
{
if (m_Open)
{// 得到当前位置
MCI_STATUS_PARMS StatusP;
DWORD dwPos;
StatusP.dwItem = MCI_STATUS_POSITION;
mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP);
dwPos = StatusP.dwReturn;
// 将当前位置增加
dwPos += (DWORD) nSeconds * 1000;
// 停止并寻找位置
MCI_SEEK_PARMS SeekP;
SeekP.dwTo = dwPos;
if (m_Playing && !m_Pause)
mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);
mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &SeekP);
// 恢复播放
if (m_Playing && !m_Pause)
Play ();
}
}
void CExMidi::Backward (int nSeconds)
{
if (m_Open)
{
MCI_STATUS_PARMS StatusP;
DWORD dwPos;
StatusP.dwItem = MCI_STATUS_POSITION;
mciSendCommand (m_wDeviceID, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID) &StatusP);
dwPos = StatusP.dwReturn;
dwPos -= (DWORD) nSeconds * 1000;
MCI_SEEK_PARMS SeekP;
SeekP.dwTo = dwPos;
if (m_Playing && !m_Pause)
mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);
mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &SeekP);
if (m_Playing && !m_Pause)
Play ();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?