概述
VC++ 开发工具中声音的处理
1、利用高级音频函数播放波形音频文件
Windows 提供了三个播放声音的高级音频函数: MessageBeep 、 PlaySound 和 sndPlaySound 。
(1)MessageBeep() 函数:
函数原型: BOOL MessageBeep(UINT uType);
函数功能:播放系统报警声音。
说明:①系统报警声音是由用户在控制面板中的声音程序定义的,或在 WIN.INI 的 [sound] 段中定义的。
② uType 说明了报警级别,参数值如下:
-1:从机器的扬声器中发出蜂鸣声
MB_ICONASTERISK :播放由 SystemAsterisk 定义的声音
MB_ICONEXCELAMATION: 播放由 SystemExclamation 定义的声音。
MB_ICONHAND :播放由 SystemHand 定义的声音。
MB_ICONQUESTION :播放由 SystemHand 定义的声音。
MB_OK :播放由 SystemDefault 定义的声音。
(2) PlaySound() 函数:
函数原型: BOOL PlaySound(LPCSTR pszSound,HMODULE hmod,DWORD fdwSound);
函数功能:播放音频文件
说明:①该函数有两个限制:必须将声音数据完整地载入物理内存;数据格式必须被所配置的某一音频驱动器的支持。
② PlaySound() 通常用于100 K 以下的文件。
③参数说明: pszSound :指定了要播放声音的字符串,该参数可以是 WAVE 文件的名字或 WAV 资源的名字,或是内存中声音数据的指针,或是在系统注册表 WIN.INI 中定义的系统事件的声音。
hmod :是应用程序的实例句柄,当播放 WAV 资源时要用到该参数。
fdwSound :是标志的组合,参数值如下:
SND_APPLICATION: 用应用程序指定的关联来播放声音。
SND_ALIAS:pszSound 参数指定了注册表或 WIN.INI 中的系统事件的别名。
SND_FILENAME:pszSound 参数指定了 WAVE 文件名。
SND_LOOP: 重复播放声音,必须与 SND_ASYNC 标志一起使用。
SND_MEMORY: 播放载入到内存中的声音,此时 pszSound 是指向声音数据的指针。
SND_SYNC: 同步播放声音,在播放完后 PlaySound 函数才返回。
例如:在 C:WINDOWS|MEDIA 目录下有一名为 data.wav 的声音文件,调用 PalySound() 函数播放声音文件的方法有:
方法1:直接播出声音文件:代码如下:
PlaySound(“C:\windowsmediadata.wav”,NULL,SND_FIMENAME|SND_ASYNC);
方法2:把声音文件加入到资源中,然后从资源中播放。假定声音资源的 ID 为: IDR_DATA ,则代码为:
PlaySound((LPCTSTR)IDR_DATA,AfxGetInstanceHandle(),SND_RESOURCE|SND_ASYNC);
另外用 PlaySound 还可以播放系统声音,代码如下:
PlaySound(“SystemStart”,NULL,SND_ALIAS|AND_ASYNC);
(3)sndPlaySound() 函数:
函数原型: BOOL sndPlaySound(LPCSTR lpszSound,UINT fuSound);
功能:播放声音文件。
说明:除了不能指定资源名字之外,其他参数功能和 PlaySound() 函数一样。
例如: sndPlaySound(“data.wav”,SND_ASYNC);
例 1:EX3_1: 编写一个 SDI 程序测试 MessageBeep,PlaySound,sndPlaySound 三个函数。
步骤:(1)拷贝一个波形文件 tada.wav 到刚创建的工程目录下。
(2)在工程中加入多媒体组件。选择 Project|Add to Project|Compents and Controls 菜单项,在弹出的 Compents and Control Gallery 对话框中选择 Visual C++Compents 文件夹,然后选择 Windows Multimedia library 选项,将其插入工程中。
(3)编辑资源菜单,加入函数测试菜单项,添加如下子菜单的属性和 ID 值。
属性: MessageBeep ID:ID_MESSAGEBEEP
属性: PlaySound ID:ID_PLAYSOUND
属性: sndPlaySound ID:ID_SNDPLAYSOUND
(4)利用类向导为这些消息生成视图类的相应处理函数,并添加代码:
void CMainFrame::OnMessagebeep()
{
// TODO: Add your command handler code here
MessageBeep(MB_OK); // 播放系统默认的声音
}
void CMainFrame::OnPlaysound()
{
// TODO: Add your command handler code here
PlaySound("friendonline.wav",NULL,SND_LOOP|SND_ASYNC);
}
void CMainFrame::OnSndpaysound()
{
// TODO: Add your command handler code here
sndPlaySound("ringout.wav",SND_ASYNC);
}
程序运行图如下:
程序运行结果: 程序代码下载: |
2、利用 MCI 播放声音:
应用程序通过向 MCI 发送命令来控制媒体设备。利用 MCI 函数,可以把命令发送到任何设备,每个设备的有效命令取决于设备本身的能力,如发送开始、播放、结束等命令。运用 MCI 函数可以播放 WAV 文件、 MIDI 文件以及视频( AVI )文件等。
MCI 命令接口分命令字符和命令消息两种,两者功能相同,命令字符串具有使用简单的特点,但它的执行效率不如命令消息。
( 1 )用命令字符串访问 MCI 命令接口
所有的 MCI 命令字符串都是通过多媒体 API 函数 mciSendString 传递给 MCI 的,该函数的原型为:
MCIERROR mciSendString
(
LPCTSTR plszCommand, //MCI 命令字符串
LPTSTR lpszReturnString, // 存放反馈信息的缓冲区
UINT cchReturn, // 缓冲区的长度
HANDLE hwndCallback // 回调窗口的句柄,一般为 NULL
); // 若成功返回 0 。否则返回错误码
例如:一个使用 mciSendString 的简单的例子。
Char buf[50];
MCIERROR mciError;
mciError=mciSendString(“open data.wav type waveaudio”,buf,strlen(buf),NULL);
(2)用命令消息访问 MCI 命令接口
与 MCI 命令字符串相比, MCI 命令消息的执行速度更快,所有的 MCI 命令消息都是通过 mciSendCommand 函数发送的 。
函数原型为:
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice, // 设备的 ID ,在打开设备时不用该参数
UINT uMsg ,// 命令消息
DWORD fdwCommand, // 命令消息的标志
DWORD dwParam // 指向包含命令消息参数的结构
); // 若成功返回 0 ,否则返回错误码
功能:播放音频文件。
说明:为使用 MCI 函数 mciSendCommand 来播放一个波形文件,需要数据结构 MCI_PLAY_PARAMS 和 MCI_WAVE_OPEN_PARMS 。
MCI_WAVE_OPEN_PARMS 的数据结构:
typedef struct
{
DWORD dwCallback; // 如果指定 MCI_NOTIFY 标志,为回调的窗口句柄。
MCIDEVICEID wDeviceID;// 返回的设备标识符
LPCSTR lpstrDeviceType;// 指定设备类型
LPCSTR lpstrElementName;// 指向设备元素名称的指针,通常是一个路径。
LPCSTR lpstrAlias;// 设备别名
DWORD dwBufferSeconds;// 指出以秒计量的缓冲区的长度
} MCI_WAVE_OPEN_PARMS;
MCI_PALY_PARAMS 的结构为:
Typedef strut
{
DWORD dwCallback; // 如果指定 MCI_NOTIFY 标志,为回调的窗口句柄。
DWORD dwFrom; // 开始播放的文件位置
DWORD dwTo; // 结束播放的文件位置
}MCI_PLAY_PARAMS;
用命令消息控制播放波形文件的机制:
(1)打开波形音频设备
UINT wDeviceID;
DWORD dwReturn;
MCI_OPEN_PARMS OpenParms;
OpenParms.lpstrDeviceType=(LPCSTR)MCI_DEVTYPE_WAVEAUDIO; // 波形音频类型
OpenParms.lpstrElementName=(LPCSTR)Filename;
OpenParms.wDeviceID=0;
mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPENELEMENT,(DWORD)(LPVOID)&OpenParms);
(2)关闭波形音频设备
mciSendCommand(m_wDeviceID,MCI_CLOSE,NULL,NULL);
(3)播放
MCI_PLAY_PARMS PlayParms;
PlayParms.dwFrom=0;
mciSendCommand(m_wDeviceID,MCI_PLAY,MCI_FROM,(DWORD)(LPVOID)&PlayParms));
(4)暂停
MCI_PLAY_PARMS PlayParms;
mciSendCommand(m_wDeviceID,MCI_PAUSE,0,(DWORD)(LPVOID)&PlayParms);
(5)停止
mciSendCommand(m_wDeviceID,MCI_STOP,NULL,NULL);
例 2 : Ex3_2 :编写一个应用程序,利用 mciSendString 函数和 mciSendCommand 函数来对波形音频文件的播放进行控制。
步骤:( 1 )利用 MFC AppWizard(EXE) 生成一个基于对话框的应用程序,项目名为 Ex2_2 。
( 2 )选择资源视图,编辑对话框 IDD_Ex2_2_DIALOG 。
删除对话框上原有的按钮和静态文本控件,从控制面板上选择 4 个按钮控件加入对话框中,并用 group 控件将它们编为一组,如下设置这些控件的 ID 和标题。
标题( Caption ) ID 值
Open IDC_BUTTON_OPEN
Play IDC_BUTTON_PLAY
Pause IDC_BUTTON_PAUSE
Stop IDC_BUTTON_STOP
MciSendCommand(group 控件 ) IDC_STATIC
mciSendStringTest IDC_STATIC
CommandString IDC_STATIC
Edit 无标题 IDC_COMMANDSTRING
Play IDC_BUTTON_STR_PLAY
(3)利用类向导为对话框上的控件添加相应的成员函数和成员变量。
对象 ID 消息处理函数
IDC_BUTTON_OPEN OnButtonOpen()
IDC_BUTTON_PLAY OnButtonPlay()
IDC_BUTTON_PAUSE OnButtonPause()
IDC_BUTTON_STOP OnButtonStop()
IDC_BUTTON_STR_PLAY OnButtonStrPlay()
IDOK OnOK()
(4)为了响应 MCI 消息 MM_MCINOTIFY ,需要手工添加相应的消息函数的声明:
在 Ex3_2Dlg.h 文件中添加红体语句:
//}}AFX_MSG
afx_msg LRESULT OnMciNotify(WPARAM wParam,LPARAM lParam);
DECLARE_MESSAGE_MAP()
在 Ex3_2Dlg.cpp 文件中加入消息映射部分红体代码:
BEGIN_MESSAGE_MAP(CEx3_2Dlg, CDialog)
//{{AFX_MSG_MAP(CEx3_2Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_PAUSE, OnButtonPause)
ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
ON_BN_CLICKED(IDC_BUTTON_STR_PLAY, OnButtonStrPlay)
//}}AFX_MSG_MAP
ON_MESSAGE(MM_MCINOTIFY,OnMciNotify)
END_MESSAGE_MAP()
(5)添加 Windows 的多媒体组件:选择 Project|Add to Project|Compents and Control|C++Compents|Windows Multimedia library 。
(6)在 Ex3_2Dlg.h 中添加三个保护类型的成员变量:
protected:
HICON m_hIcon;
BOOL m_bIsPlay; // 指示是否正在播放
BOOL m_bIsPause;// 指示是否处于暂停状态
MCIDEVICEID m_MCIDeviceID; // 设备 ID
编写消息处理函数的代码:
void CEx3_2Dlg::OnButtonOpen()
{
// TODO: Add your control notification handler code here
CString filename;
MCI_OPEN_PARMS mciOpenParam;
DWORD dwError;
static char szFilter[]="waveaudio file(*.wav)|*.wav||";
CFileDialog dlg(TRUE,"wav",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
if(dlg.DoModal()==IDOK)
{
filename=dlg.GetPathName();
if(m_bIsPlay)
{
dwError=mciSendCommand(m_MCIDeviceID,MCI_CLOSE,0,NULL);
}
mciOpenParam.lpstrDeviceType="waveaudio";
mciOpenParam.lpstrElementName=filename;
dwError=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParam);
m_MCIDeviceID=mciOpenParam.wDeviceID;
m_bIsPlay=FALSE;
m_bIsPause=FALSE;
}
}
void CEx3_2Dlg::OnButtonPause()
{
// TODO: Add your control notification handler code here
DWORD dwError;
if(m_bIsPlay)
{ dwError=mciSendCommand(m_MCIDeviceID,MCI_PAUSE,0,NULL);
m_bIsPause=!m_bIsPause;
}
if(!m_bIsPlay)
{
m_bIsPause=FALSE;
}
}
void CEx3_2Dlg::OnButtonPlay()
{
// TODO: Add your control notification handler code here
MCI_PLAY_PARMS mciPlayParms;
DWORD dwError;
if(!m_bIsPlay)
{
mciPlayParms.dwCallback=(long)GetSafeHwnd();
mciPlayParms.dwFrom=0;
dwError=mciSendCommand(m_MCIDeviceID,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);
}
if(m_bIsPlay&&m_bIsPause)
{
dwError=mciSendCommand(m_MCIDeviceID,MCI_RESUME,0,NULL);
m_bIsPause=!m_bIsPause;
}
m_bIsPlay=TRUE;
}
void CEx3_2Dlg::OnButtonStop()
{
// TODO: Add your control notification handler code here
DWORD dwError;
dwError=mciSendCommand(m_MCIDeviceID,MCI_STOP,MCI_WAIT,NULL);
mciSendCommand(m_MCIDeviceID,MCI_CLOSE,NULL,NULL);
}
void CEx3_2Dlg::OnButtonStrPlay()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
DWORD ok=mciSendString("play aa.wav type waveaudio",NULL,0,NULL);
}
void CEx3_2Dlg::OnOK()
{
// TODO: Add extra validation here
OnButtonStop();
CDialog::OnOK();
}
//MM_MCINOTIFY
LRESULT CEx3_2Dlg::OnMciNotify(WPARAM wParam,LPARAM lParam)
{
if(wParam==MCI_NOTIFY_SUCCESSFUL)
{
m_bIsPlay=FALSE;
m_bIsPause=FALSE;
return 0;
}
return -1;
}
程序运行结果图:
程序运行结果: 程序代码下载: |
本文来源:http://wwww.ahtvu.ah.cn/jxc/40vc/student1/zhixin/ch9/a22.htm
最后
以上就是任性小蘑菇为你收集整理的VC++ 开发工具中声音的处理的全部内容,希望文章能够帮你解决VC++ 开发工具中声音的处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复