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 <Windows.h>#include<mmsystem.h>#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);//方法1PlaySound("空音轨.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/121686347https://blog.csdn.net/seektostart/article/details/9429711
C语言课设分享:bgm相关推荐
- C语言课设分享:图片加载
前言: 本教程仅针对EasyX函数库中的加载图片功能进行代码优化,均为本人自己的经验总结,如有问题和指正欢迎在评论区留言 目录: 文章目录 前言: 目录: 一.问题所在 二.不同方案的对比 1.直接定 ...
- c语言售票系统主要函数,c语言课设电影院售票系统.docx
struct inf { char rate[20]; char name[20]; int time_hour; int time_min; int seat; int sell; }inf[10] ...
- 课设 c语言编译学籍管理系统,C语言课设之学生学籍管理系统
<C语言课设之学生学籍管理系统>由会员分享,可在线阅读,更多相关<C语言课设之学生学籍管理系统(10页珍藏版)>请在人人文库网上搜索. 1.题目:学生学籍管理系统 目录:一.个 ...
- 0英文基础 学c语言 词典,C语言课设之英文词典排标准系统
<C语言课设之英文词典排标准系统>由会员分享,可在线阅读,更多相关<C语言课设之英文词典排标准系统(21页珍藏版)>请在人人文库网上搜索. 1.1 / 19一种简单的英文词典排 ...
- c语言设计之歌曲信息管理系统,C语言课设之歌曲信息管理系统
<C语言课设之歌曲信息管理系统>由会员分享,可在线阅读,更多相关<C语言课设之歌曲信息管理系统(10页珍藏版)>请在人人文库网上搜索. 1.C语言课程设计目 录1.题目要求2. ...
- c语言学生成绩查询课设报告,C语言课设报告(学生考试成绩查询程序)【荐】.doc...
C语言课设报告(学生考试成绩查询程序)[荐].doc 学生考试成绩查询程序 学号:******** 姓名:***** 完成日期:****年月 通过键盘输入学生的考试信息,包括:学号.姓名.课程名称.学 ...
- 学生信息管理系统c语言课设,学生信息管理系统C语言课设.doc
学生信息管理系统C语言课设 目录 一.需求分析2 二.概要设计2 三.详细设计4 四.调试分析9 五.用户手册9 六.测试数据9 七.附录10 一.需求分析学生学籍管理系统用数据文件存放学生的学籍,可 ...
- c语言学生学籍管理修改,C语言课设之学生学籍管理系统.doc
C语言课设之学生学籍管理系统.doc 题目学生学籍管理系统 目录一.个人简介.二.报告摘要.三.报告目录.四.报告正文. 1.系统需求分析 2.系统总体设计 3.系统详细设计六.总结. 二.报告摘要 ...
- C语言课设物资管理系统,C语言课设之物资管理系统.doc
C语言课设之物资管理系统 C语言课程设计 目 录 1.需求分析: 2.系统总框图: 3.每个模块的设计分析: 4.列出所有定义的函数及说明: 5.举例说明1.2个比较有特点的算法: 6.数据分析.完备 ...
- 电影院选票系统(C语言课设)
这里给到大家介绍一个自己写的C语言课设的代码,代码功能不是很完善,只有很基础的增删改查 题目 :电影院选票系统 功能 :放映厅 ,电影信息的 增删改查,以及排序 系统要求实现以下功能: 1.输入功能: ...
最新文章
- leetcode算法题--二进制求和
- 权限框架 - shiro 简单入门实例
- Spoken English(015)
- Android事件分发浅析
- 利用机器学习的排名模型,提升你在英雄联盟的排名
- PAT 1068. 万绿丛中一点红(20)-乙级
- CodeForces - 729D
- DiskFileUpload上传文件并获取前端表单数据
- 机器学习--digits手写字体
- 计算机自动隐藏桌面图标,AutoHideDesktopIcons-定时、自动隐藏桌面图标,让电脑更清爽!...
- 国产龙芯笔记本(on 龙芯2F)的使用体验
- 爬虫-抖音无水印视频下载
- 免费开通量化软件恒生ptrade和讯投qmt
- python软件操作步骤_python+pywinauto C/S架构软件基本操作
- pandas学习task05变形
- 计算机学院运动会解说词,学校运动会解说词30篇
- 教程篇(7.0) 04. FortiGate基础架构 二层交换 ❀ Fortinet 网络安全专家 NSE 4
- 群体智能的发展现状:AI网络安全现状、新一代AI发展现状
- 一个男人写给前女友的话。。。真心哭了
- 李佳琦转行成直播一哥,他做对了哪些事?