当前位置: 源码素材网 » VC++教程 » 详情页

VC++播放WAV文件的代码

  •   时间:2019-05-11
  • 概述:WAV 播放器

VC++播放WAV文件,本例将建立一个Cwave 类,其中封装MCI 控制函数以便方便地控制和播放WAV 文件。MCI(Media Control Interface)媒体控制接口是MircroSoft 公司提供的一组多媒体设备和文件的标准接口,它的好处是可以方便地控制绝大多数多媒体设备,包括音频、视频、影碟、录像等多媒体设备,而不需要知道它们的内部工作状况。

程序代码编写说明:

(1)新建一个单文档项目PlayWave。编辑资源菜单,新建一个【播放】菜单,下设【打开…】、【开始播放】、【停止播放】和【退出】4 个子菜单项。它们的ID 标识依次为ID_OPEN、ID_PLAY、ID_STOP 和ID_APP_EXIT。

(2)利用ClassWizard 或ClassView 从CObject 派生出一个新类CWave,并添加如下成员变量。

#include <mmsystem.h>
class CWave:public CObject
{
…
protected:
MCIDEVICEID m_nDeviceID;
MCIDEVICEID m_nElementID;
};

由于要调用MCI 接口函数,需要将<mmsystem.h>包含到本项目中来,并在项目设置选项中添加库文件winmm.lib,这样才能使用Windows 的多媒体功能。
(3)利用ClassView 为CWave 类添加一个成员函数OpenDevice,用于打开波形音频设备。代码如下:

DWORD CWave::OpenDevice()
{
DWORD dwResult=0;
if ( !m_nDeviceID )
{
MCI_OPEN_PARMS mciOpenParms;
mciOpenParms.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;
// 打开波形音频设备
dwResult=mciSendCommand(NULL,MCI_OPEN,
MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_WAIT,
(DWORD)(LPVOID)&mciOpenParms);
// 保存设备标识,供后面其他MCI 命令使用
m_nDeviceID=mciOpenParms.wDeviceID;
if(dwResult)
DisplayErrorMsg(dwResult);
}
return dwResult;
}

(4)利用ClassView 为CWave 类添加一个成员函数CloseDevice,用于关闭波形音频设备。代码如下:

DWORD CWave::CloseDevice()
{
DWORD dwResult=0;
if(m_nDeviceID)
{
// 关闭波形音频设备
dwResult=mciSendCommand(m_nDeviceID,MCI_CLOSE,NULL,NULL);
if(dwResult)
DisplayErrorMsg(dwResult);
else
m_nDeviceID=0;
}
return dwResult;
}

(5)利用ClassView 为CWave 类添加一个成员函数Play,用于播放WAV 文件。代码如下:

DWORD CWave::Play(CWnd* pWnd,LPCSTR pFileName)
{
MCI_OPEN_PARMS mciOpenParms;
memset(&mciOpenParms,0,sizeof(MCI_OPEN_PARMS));
// 设置要播放的WAV 的文件名
mciOpenParms.lpstrElementName=pFileName;
// 打开WAV 文件
DWORD dwResult=mciSendCommand(m_nDeviceID,MCI_OPEN,
MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);
if(dwResult)
DisplayErrorMsg(dwResult);
else
{
// 保存音频元素的标识
m_nElementID=mciOpenParms.wDeviceID;
MCI_PLAY_PARMS mciPlayParms;
// 设置接收通知消息的窗口
mciPlayParms.dwCallback=(DWORD)pWnd->GetSafeHwnd();
// 播放WAV 文件
dwResult=mciSendCommand(m_nElementID,MCI_PLAY,MCI_NOTIFY,
(DWORD)(LPVOID)&mciPlayParms);
if(dwResult)
{
DisplayErrorMsg(dwResult);
Stop();
}
}
return dwResult;
}

(6)利用ClassView 为CWave 类添加一个成员函数Stop,用于停止WAV 文件的播放。代码如下:

DWORD CWave::Stop()
{
DWORD dwResult=0;
if(m_nElementID)
{
dwResult=mciSendCommand(m_nElementID,MCI_CLOSE,NULL,NULL);
if(dwResult)
DisplayErrorMsg(dwResult);
else
m_nElementID=0;
}
return dwResult;
}

(7)利用ClassView 为CWave 类添加一成员函数DisplayErrorMsg,在发生错误时显示错误信息。代码如下:

void CWave::DisplayErrorMsg(DWORD dwError)
{
if(dwError)
{
char szErrorMsg[MAXERRORLENGTH];
// 获取错误描述信息
if(!mciGetErrorString(dwError,szErrorMsg,sizeof(szErrorMsg)))
strcpy(szErrorMsg,"Unknown Error");
AfxMessageBox(szErrorMsg);
}
}

(8)编辑CWave 类的析构函数,停止播放WAV 文件并关闭波形音频设备。代码如下:

CWave::~CWave()
{
if(m_nElementID)
Stop();
if(m_nDeviceID)
CloseDevice();
}

(9)为CMainFrame 类添加1 个CWave 类的成员变量m_wave,以便控制WAV 文件的播放和停止,添加一个逻辑型成员变量m_bPlay,用以标识当前播放状态,并作为控制【停止播放】按钮是否可用的判断依据。CmainFrame 初始化时,需要设置m_bPlay 为FALSE,并打开MCI 设备。CmainFrame释放内存之前要判断是否正在播放WAV 文件,如是则先停止播放并关闭MCI 设备。代码如下:

CMainFrame::CMainFrame()
{
m_bPlay=FALSE;
m_wave.OpenDevice();
}
CMainFrame::~CMainFrame()
{
if( m_bPlay )
{
m_wave.Stop();
m_wave.CloseDevice();
}
}

(10)在CMainFrame 类中添加【打开】菜单命令的消息处理函数,播放指定的WAV 文件。代码如下:

void CMainFrame::OnOpen()
{
CFileDialog FileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,
"Wave Files (*.wav)|*.wav||");
if (FileDlg.DoModal()==IDCANCEL) return;
if( m_bPlay )
{
m_wave.Stop();
m_bPlay=FALSE;
}
CString strFileName=FileDlg.GetPathName();
if( !m_nType )
sndPlaySound(strFileName,SND_ASYNC);
else
{
m_bPlay=TRUE;
m_wave.Play(this,strFileName);
}
}

(11)在CMainFrame 类中添加【停止播放】菜单命令的消息处理函数,停止播放WAV 文件。代码如下:

void CMainFrame::OnStop()
{
if( m_bPlay )
{
m_wave.Stop();
m_bPlay=FALSE;
}
}

(12)在CMainFrame 类中手工添加MCI 的通知消息MM_MCINOTIFY 的处理函数,该消息在播放完毕后发出。代码如下:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
…
//}}AFX_MSG_MAP
ON_MESSAGE(MM_MCINOTIFY, OnMCINotify)
END_MESSAGE_MAP()
LRESULT CMainFrame::OnMCINotify(WPARAM wParam, LPARAM lParam)
{
m_bPlay=FALSE;
return 0;
}

    相关声明:

      若“VC++播放WAV文件的代码”有损您的权益,请告之我们删除内容。
      部分文章来源于网络,版权归原作者所有。