其实win32API中,声音处理说简单也简单,说麻烦也麻烦。
常用也就是两种方式,一种是采用函数PlaySound;另一种是使用mciSendString函数。至于sndPlaySound、mciSendCommand这些也是可以,但是大同小异。
采用声音函数之前,先要收入相关的头部文件:
#include <windows.h> //相关的常量
.....
#pragma comment(lib, "winmm.lib")//声音库文件
一、PlaySound函数
1,直接引用wav文件。这种方式最简单,用法如下:
PlaySound (TEXT ("coin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
该函数的声明方式如下:
BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);
pszSound,指定要播放声音的字符串;
hmod是应用程序的实例句柄,当播放WAV资源时要用到该参数,否则它必须为NULL;
fdwSound是标志的组合,列几个常用的:
(1),SND_FILENAME,pszSound参数指定了WAVE文件名。
(2),SND_ASYNC,用异步方式播放声音,PlaySound函数在开始播放后立即返回。
(3),SND_RESOURCE,pszSound参数是WAVE资源的标识符,这时要用到hmod参数。
2,采用SND_RESOURCE。
//rc文件:
IDW_WAVE_COIN WAVE DISCARDABLE "sound\\coin.wav"
...
//cpp文件:
PlaySound((LPCTSTR)IDW_WAVE_COIN,GetModuleHandle(NULL),SND_RESOURCE | SND_ASYNC);
有时侯这个代码会出现defaultlib "LIBCD" conflicts的警告,可以如下设置:
project setting -> link ->project opinion 后面加内容/NODEFAULTLIB:LIBC
采用SND_RESOURCE方式一般来说要更好一些,可以让wav文件长驻内存(去掉DISCARDABLE标识符),而且还可以将wav文件打包进exe文件。
二、mciSendString函数
这个函数相对比较底层,用法比较复杂,大体如下:
void playMap3(TCHAR* fileName){
TCHAR szBuffer[1024];
MCIERROR mciError;
wsprintf(szBuffer,TEXT("open %s alias OpenFile type MPEGVideo"),fileName);
mciSendString ("close OpenFile", NULL, 0, NULL) ;
mciError = mciSendString (szBuffer, NULL, 0, NULL) ; //打开
mciSendString ("play OpenFile", NULL, 0, NULL) ;
}
mciSendString函数的优势是可以播放mp3文件,而PlaySound只能播放wav文件;劣势是这个方法反应很慢,有延迟,而且用法也比较复杂,目前还不知道它怎么异步播放文件,当然可以采取另开一线程的作法:
void Thread1 (PVOID pvoid){
TCHAR* fileName= (TCHAR*) pvoid ;
playMap3(fileName);
}
当然采用线程的话,还要设置编译模式,加入另外的头文件等。
总 结
虽然mciSendString比较底层,操作空间比较大,能支持更多格式,但用法比较复杂,而且速度慢,所以个人还是建议采用PlaySound,这个方法使用简单,不需要多线程模式,遇见其它格式文件时,用工具转换成wav格式即可,不用那么折腾。