C/C++——如何使用PlaySound同时播放两个声音

PlaySound是Windows用于播放音乐的API函数。在vs2010以上版本需要加入#pragma comment(lib, “winmm.lib”)才能使用PlaySound(或者在构建选项的连接中添加winmm)。
winmm
PlaySound函数原型为 BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound)。
参数pszSound是指定了要播放声音的字符串,该参数可以是WAVE文件的名字,或是WAV资源的名字,或是内存中声音数据的指针,或是在系统注册表WIN.INI中定义的系统事件声音,如果该参数为NULL则停止正在播放的声音。
参数hmod是应用程序的实例句柄,除非pszSound的指向一个资源标识符(即fdwSound被定义为SND_RESOURCE),否则必须设置为NULL。
参数fdwSound是标志的组合,如下表所示:

标志 效果
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)显示音量滑块控制系统通知的声音。设置该标志将下控制音量滑块。如果没有设置该标志,声音是分配到默认的音频会议的应用进程

由于PlaySound()本身就是采用多线程来播放声音的,所以即使采用多线程同时执行PlaySound()试图播放多个声音,后执行的PlaySound()的声音也会覆盖掉之前的声音。因此,只有考虑用多进程解决这个问题了。为了使得程序可以同时播放背景音乐和音效,可以再开一个进程负责播放背景音乐,主进程通过pipe联系子进程来切换背景音乐。代码如下:

#include <windows.h>
#include <fcntl.h>  
#include <process.h> 
#include <iostream>
int hpipe[2];

void setbgm(int b)//主程序调用,输入数字来设置BGM
{
	int bgm=b;
	write(hpipe[1],&bgm,sizeof(int));
}

int main(int argc,char* argv[])
{  
	char hstr[20];  
	int pid;
	if(argc==1)//主进程
    {
    	//管道初始化
		setvbuf(stdout,NULL,_IONBF,0);
		if(_pipe(hpipe,256,O_BINARY)==-1)exit(1);
		itoa(hpipe[0],hstr,10);  
		if((pid=spawnl(P_NOWAIT,argv[0],argv[0],hstr,NULL))==-1)exit(1);
		
		//以下为程序其他部分	
	    PlaySound("3.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);//主进程播放的声音
    	setbgm(1);//通知子进程切换1号BGM
    	Sleep(5000);
    	setbgm(2);//通知子进程切换2号BGM
    	Sleep(10000);
    	setbgm(-1);//程序结束前调用来关闭子程序
    }
	else//子进程
	{
		system("title BGM");
		int bgm;
		hpipe[0]=atoi(argv[1]);
		while(1)
		{
			if(read(hpipe[0],&bgm,sizeof(int)))//接收消息
			{
				switch(bgm)
				{
					//子程序退出
					case -1:exit(0);
					//1号BGM
					case 1:PlaySound("1.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);break;
					//2号BGM
					case 2:PlaySound("2.wav",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);break;
				}
			}
			Sleep(100);//防止CPU占用过高
		}
	}
}

猜你喜欢

转载自blog.csdn.net/Eyizoha/article/details/89398810