栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言课设分享bgm

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言课设分享bgm

前言:

本教程仅针对C语言的单线程播放bgm功能,均为本人查阅使用后总结,如有问题和指正欢迎在评论区留言
在播放bgm的时候,我们常常要考虑如何才能让bgm和其他音效同时播放的问题,而网络上很多答复是使用多线程
众所周知多线程的上手难度较高,因此我在这里提供一个思路来规避多线程操作,用简单的单线程就可以实现兼顾bgm和音效的播放

文章目录
  • 前言:
    • 一、运行前提
      • 1.函数:实现bgm的播放共需要2个函数
        • (1)PlaySound函数:
        • (2)mciSendString函数
      • 2.头文件需求:
    • 二、使用思路
      • 1.基本思路
      • 2.静音bgm的实现
        • (1)使用mciSendString做bgm
        • (2)使用PlaySound做bgm
    • 三、注意事项&&常见问题
      • 1.PlaySound无法播放的问题
        • (1)格式问题
        • (2)检测播放问题
      • 2.mciSendString无法播放的问题
        • (1)格式问题
        • (2)解决方案
        • (3)检测播放问题

一、运行前提 1.函数:实现bgm的播放共需要2个函数 (1)PlaySound函数:

适用于播放非BGM的声音,原型:

 BOOL PlaySound (LPCSTR pszSound, HMODULE hmod,DWORD fdwSound)

其中三个变量分别是:pszSound要播放的音频的相对位置(字符串表示)、hmod资源指示符(一般为NULL即可)、fdwSound播放模式

常用的播放模式有:

​ SND_FILENAME pszSound参数指定WAV文件名(使第一个参数生效的,必须有)

​ SND_ASYNC 用异步方式播放声音,PlaySound函数在开始播放后立即返回(在程序进行时播放,不会影响其他代码正常运行,即不会让游戏停下来等音频播放)

​ SND_SYNC 同步播放声音,在播放完后PlaySound函数才返回(会让游戏停下来等音乐播放,只是为了和上面的对比,实际上不会用)

​ SND_LOOP 重复播放声音,必须与SND_ASYNC标志一块使用(可选,让音频重复播放的)

多个播放模式中间用或 “ | ” 连接

具体使用例子:

PlaySound("叮.wav", NULL, SND_FILENAME | SND_ASYNC);
(2)mciSendString函数

适用于bgm的播放,原型:

MCIERROR mciSendString( LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback)

其中的四个变量只需要了解第一个即可,如果只是播放bgm的话,剩下三个变量分别为NULL,0,NULL

PS:因为mciSendString是MCI(Media Control Interface,媒体控制接口)的一个函数,顾名思义是播放媒体的,不仅能播放音频还能播放视频,因此剩下三个变量是为播放视频等准备的,如需了解请参考这位dalao的MCI详解,这里不做过多赘述

而第一个参数是一个String型的变量,共包含3个部分:命令,文件名称,其他操作

命令:open(打开音频),play(播放已打开的音频),close(关闭) ——类似C语言中对文件的操作

文件名称:

2.头文件需求:
#include 

#include

#pragma comment(lib,"Winmm.lib")
二、使用思路 1.基本思路

推荐使用mciSendString播放bgm,使用PlaySound播放游戏内各种音效

原因:由于mciSendString播放的时候,如果一个bgm已经在播放了,那么新播放的bgm不会生效,例如:

	mciSendString(TEXT("open bgm1.mp3 alias BGM1"), NULL, 0, NULL);	
	mciSendString(TEXT("open bgm2.mp3 alias BGM2"), NULL, 0, NULL);
	mciSendString(TEXT("play BGM1 repeat"), NULL, 0, NULL);
	mciSendString(TEXT("play BGM2 repeat"), NULL, 0, NULL);

则播放的只有bgm1.mp3

因此如果用mciSendString播放一个bgm则没有任何问题,如果用它播放音效则会出现前一个还没有播放完,后一个音效就不出声的问题。

而PlaySound由于拥有参数fdwSound来控制播放模式,正常的 SND_ASYNC (异步播放模式)就可以达到让后一个音效播放时覆盖前一个音效的效果了。

如果有个别音效需要不覆盖前面的音效(即模仿mciSendString播放逻辑的话),可以使用播放模式SND_NOWAIT 来实现,它的作用是"如果驱动程序正忙则函数就不播放声音并立即返回"。

例如:

PlaySound("音效1.wav", NULL, SND_FILENAME | SND_ASYNC);
PlaySound("音效2.wav", NULL, SND_FILENAME | SND_ASYNC);
PlaySound("音效3.wav", NULL, SND_FILENAME | SND_ASYNC | SND_NOWAIT);
Sleep(1000);
PlaySound("音效4.wav", NULL, SND_FILENAME | SND_ASYNC | SND_NOWAIT);

则最后结果为:

​ 音效1一定不会播放(被音效2覆盖了)

​ 音效2一定会播放

​ 音效3一定不会播放

​ 音效4不一定播放(如果音效2比1秒长不播放,否则播放)

写到这里我有一个奇思妙想,有没有同学帮我实现一下:如果mciSendCommand和mciSendString交替使用可不可以实现音频覆盖,从而达到PlaySound的结果?很明显这个东西并不实用

2.静音bgm的实现 (1)使用mciSendString做bgm
bool music=1;
if("开/关bgm的操作"){
    music = !music;
    if (music) {
        mciSendString("open bgm.mp3 alias BGM", NULL, 0, NULL);
        mciSendString("play BGM repeat", NULL, 0, NULL);
    }
    else {
        mciSendString("close BGM", NULL, 0, NULL);
    }
}
(2)使用PlaySound做bgm

有两种思路:

​ 一是使用SND_PURGE 播放模式,作用是让正在播放的音频停止播放

​ 二是播放一个无声的音频来覆盖之前的bgm,以达到"伪静音"的效果

例如:

bool music=1;
if("开/关bgm的操作"){
    music = !music;
    if (music) {
		PlaySound("bgm.wav",NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
    }
    else {
        PlaySound("bgm.wav",NULL, SND_PURGE);//方法1
        PlaySound("空音轨.wav",NULL, SND_FILENAME | SND_ASYNC);//方法2
        //方法1和方法2选择一种即可
    }
}
三、注意事项&&常见问题 1.PlaySound无法播放的问题 (1)格式问题

PlaySound只支持播放wav类型的音频

如果是其他格式的音频,如mp3格式,可以通过转码操作得到wav格式的音频

这里推荐的转码软件:格式工厂,一个免费纯净的转格式软件

(2)检测播放问题

PlaySound如果没能成功播放音频,则会出现系统提示音

这样很容易判断到底是没有执行到PlaySound函数,还是音频本身的问题

2.mciSendString无法播放的问题

相比于PlaySound而言,mciSendString并没有那么强的检测功能和兼容性,因此选做bgm还有一个好处就是使用的地方少。

(1)格式问题

mciSendString虽然支持格式更多,包括MPEG,AVI,WAV,MP3等等,其中常用音频有MP3和WAV,但是兼容性很差

首先,如果播放的是WAV格式,则要保证这个wav音频是无损的,我个人测试通过格式工厂转码过后的WAV格式是播放不了的

其次,如果是mp3格式,则要保证这个mp3是无封面且无损的,因为mp3格式的音频支持携带封面,而且常常是从音乐软件那里下载的,经常会带着封面一起下载下来,这时的mciSendString就无法播放了

(2)解决方案

如果是wav格式,请确保下载的是无损版的,推荐可以从耳聆网下载

如果是mp3格式,推荐从QQ音乐下载,不带封面而且直接就可以播放;不要用网易云下载,网易云下载的音频不能直接播放,而且貌似即使去掉封面依旧不能用

(3)检测播放问题

mciSendString并没有PlaySound那样的提示音,如果没有播放成功不会有任何响应

可以使用printf大法来检测究竟是谁出了问题

到这里就结束了

这是新人第一篇CSDN,如有谬误欢迎指正批评
特别鸣谢:提供帮助的舍友和CSDN的大佬们

参考资料:
https://blog.csdn.net/qq_42591783/article/details/121686347

https://blog.csdn.net/seektostart/article/details/9429711

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/869109.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号