PlaySound 和 sciSendString 实现音频播放的两种方式

Carewho

发布日期: 2019-01-07 18:10:43 浏览量: 1172
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

背景

大家都使用过有音效播放的软件或程序吧,这些程序可能是只播放一个提示音,也可能是播放整首音乐或曲子,又或许你自己开发一些程序或者游戏需要播放声音。Windows上播放音频的函数有很多,PlaySound 和 mciSendString 函数就是常用的两个播放声音的函数。

那么,怎么编程实现声音的播放?如果有多个声音同时播放,那应该如何实现?PlaySound 和 mciSendString 它们的使用场景有什么不同吗?带着这些疑问来阅读本文,本文会一一为你解答。现在,我就把实现原理和实现过程写成文档,分享给大家。

函数介绍

PlaySound 函数

PlaySound功能播放由给定文件名,资源或系统事件指定的声音。

函数声明

  1. BOOL PlaySound(
  2. LPCTSTR pszSound,
  3. HMODULE hmod,
  4. DWORD fdwSound
  5. );

参数

  • pszSound
    指定要播放的声音的字符串。 包括空终止符的最大长度为256个字符。 如果此参数为NULL,则任何当前播放的波形声音都将停止。 要停止非波形声音,请在fdwSound参数中指定SND_PURGE。fdwSound(SND_ALIAS,SND_FILENAME和SND_RESOURCE)中的三个标志确定名称是否被解释为系统事件,文件名或资源标识符的别名。 如果没有指定这些标志,则PlaySound将在注册表或WIN.INI文件中搜索与指定声音名称的关联。 如果找到关联,则播放声音事件。 如果在注册表中没有找到关联,则名称将被解释为文件名。

  • hmod
    处理包含要加载的资源的可执行文件。 除非在fdwSound中指定了SND_RESOURCE,否则此参数必须为NULL。

  • fdwSound
    播放标志,定义了下面的值:

VALUE MEANING
SND_APPLICATION 用应用程序指定的关联来播放声音
SND_ALIAS pszSound参数指定了注册表或WIN.INI中的系统事件的别名
SND_ALIAS_ID pszSound参数指定了预定义的声音标识符
SND_ASYNC 用异步方式播放声音,PlaySound函数在开始播放后立即返回
SND_FILENAME pszSound参数指定了WAVE文件名
SND_LOOP 重复播放声音,必须与SND_ASYNC标志一块使用
SND_MEMORY 播放载入到内存中的声音,此时pszSound是指向声音数据的指针
SND_NODEFAULT 不播放缺省声音,若无此标志,则PlaySound在没找到声音时会播放缺省声音
SND_NOSTOP PlaySound不打断原来的声音播出并立即返回FALSE
SND_NOWAIT 如果驱动程序正忙则函数就不播放声音并立即返回
SND_PURGE 停止所有与调用任务有关的声音。若参数pszSound为NULL,就停止所有的声音,否则,停止pszSound指定的声音
SND_RESOURCE pszSound参数是WAVE资源的标识符,这时要用到hmod参数
SND_SYNC 同步播放声音,在播放完后PlaySound函数才返回
SND_SYSTEM 如果这个标志被设置,声音是分配到音频会议系统通知的声音。系统音量控制程序(sndvol)显示音量滑块控制系统通知的声音。设置该标志将下控制音量滑块。如果没有设置该标志,声音是分配到默认的音频会议的应用进程

返回值

  • 如果成功返回TRUE,否则返回FALSE。

mciSendString 函数

mciSendString函数向MCI设备发送命令字符串。 在命令字符串中指定发送命令的设备。

函数声明

  1. MCIERROR mciSendString(
  2. LPCTSTR lpszCommand,
  3. LPTSTR lpszReturnString,
  4. UINT cchReturn,
  5. HANDLE hwndCallback
  6. );

参数

  • lpszCommand
    指向指定MCI命令字符串的以null结尾的字符串的指针。 有关列表,请参阅多媒体命令字符串。
  • lpszReturnString
    指向接收返回信息的缓冲区的指针。 如果不需要返回信息,该参数可以为NULL。
  • cchReturn
    由lpszReturnString参数指定的返回缓冲区的大小(以字符为单位)。
  • hwndCallback
    如果在命令字符串中指定了“notify”标志,则处理回调窗口。

返回值

  • 如果成功返回零,否则返回错误。

实现原理

由函数介绍可以知道,PlaySound 函数功能比较灵活,可以播放系统声音,也可以播放指定音频文件。音频可以是作为资源插在程序中、可以存放在内存中、还可以是本地的音频文件。但是,有一个缺点就是,使用 PlaySound 不能同时播放两个或者多个声音,因为 PlaySound 是独占播放音频文件的。如果使用 PlaySound 播放新的声音,那么之前使用它播放的声音会立即停止,从而播放新声音。要实现同时播放多个声音,需要使用 mciSendString 来实现了。

那么,使用 PlaySound 播放音频文件的代码就是:

  1. ::PlaySound(pszFileName, NULL, SND_ASYNC | SND_LOOP);

其中,pszFileName是音频文件路径;SND_ASYNC表示异步播放,SND_LOOP表示循环播放。

对于,mciSendString 函数,我在《使用mciSendString函数实现循环播放音频文件》文章中,讲过使用它来实现循环播放音乐。主要是要理解 mciSendString 的命令,其中, open 指令用于打开文件;play 指令用于播放声音;close 用于关闭声音的播放。使用方式如下所示:

  1. // 打开音频文件
  2. ::mciSendString("open filename alias mymusic", NULL, 0, NULL);
  3. // 播放音频文件
  4. ::mciSendString("play mymusic", NULL, 0, NULL);
  5. // 关闭文件, 停止播放
  6. ::mciSendString("close mymusic", NULL, 0, NULL);

使用 mciSendString 函数可以实现同时播放多个声音,在一个游戏里面,通常使用 mciSendString 函数来播放背景音乐等比较久的声音,使用 PlaySound 函数来播放比较短促的音效声音。这样,就实现了同时播放多个声音了。

编码实现

导入库文件

  1. #include <MMSystem.h>
  2. #pragma comment(lib, "winmm.lib")

PlaySound方法播放

  1. BOOL PlayMySound1(char *pszFileName)
  2. {
  3. BOOL bRet = ::PlaySound(pszFileName, NULL, SND_ASYNC | SND_LOOP);
  4. return bRet;
  5. }

mciSendString方法播放

  1. BOOL PlayMySound2(char *pszFileName)
  2. {
  3. char szCmd[MAX_PATH] = {0};
  4. // 打开音频文件
  5. ::wsprintf(szCmd, "open \"%s\" alias mymusic", pszFileName);
  6. ::mciSendString(szCmd, NULL, 0, NULL);
  7. // 播放音频文件
  8. ::mciSendString("play mymusic", NULL, 0, NULL);
  9. return TRUE;
  10. }

总结

使用 PlaySound 不能同时播放两个或者多个声音,mciSendString 函数可以同时播放多个声音。

在一个游戏里面,通常使用 mciSendString 函数来播放背景音乐等比较久的声音,使用 PlaySound 函数来播放比较短促的音效声音。这样,就实现了同时播放多个声音了。

上传的附件 cloud_download PlaySound_Test.7z ( 143.14kb, 1次下载 )

发送私信

人生没有彩排,每天都是现场直播

10
文章数
21
评论数
最近文章
eject