前言:

本教程仅针对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/121686347

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

C语言课设分享:bgm相关推荐

  1. C语言课设分享:图片加载

    前言: 本教程仅针对EasyX函数库中的加载图片功能进行代码优化,均为本人自己的经验总结,如有问题和指正欢迎在评论区留言 目录: 文章目录 前言: 目录: 一.问题所在 二.不同方案的对比 1.直接定 ...

  2. c语言售票系统主要函数,c语言课设电影院售票系统.docx

    struct inf { char rate[20]; char name[20]; int time_hour; int time_min; int seat; int sell; }inf[10] ...

  3. 课设 c语言编译学籍管理系统,C语言课设之学生学籍管理系统

    <C语言课设之学生学籍管理系统>由会员分享,可在线阅读,更多相关<C语言课设之学生学籍管理系统(10页珍藏版)>请在人人文库网上搜索. 1.题目:学生学籍管理系统 目录:一.个 ...

  4. 0英文基础 学c语言 词典,C语言课设之英文词典排标准系统

    <C语言课设之英文词典排标准系统>由会员分享,可在线阅读,更多相关<C语言课设之英文词典排标准系统(21页珍藏版)>请在人人文库网上搜索. 1.1 / 19一种简单的英文词典排 ...

  5. c语言设计之歌曲信息管理系统,C语言课设之歌曲信息管理系统

    <C语言课设之歌曲信息管理系统>由会员分享,可在线阅读,更多相关<C语言课设之歌曲信息管理系统(10页珍藏版)>请在人人文库网上搜索. 1.C语言课程设计目 录1.题目要求2. ...

  6. c语言学生成绩查询课设报告,C语言课设报告(学生考试成绩查询程序)【荐】.doc...

    C语言课设报告(学生考试成绩查询程序)[荐].doc 学生考试成绩查询程序 学号:******** 姓名:***** 完成日期:****年月 通过键盘输入学生的考试信息,包括:学号.姓名.课程名称.学 ...

  7. 学生信息管理系统c语言课设,学生信息管理系统C语言课设.doc

    学生信息管理系统C语言课设 目录 一.需求分析2 二.概要设计2 三.详细设计4 四.调试分析9 五.用户手册9 六.测试数据9 七.附录10 一.需求分析学生学籍管理系统用数据文件存放学生的学籍,可 ...

  8. c语言学生学籍管理修改,C语言课设之学生学籍管理系统.doc

    C语言课设之学生学籍管理系统.doc 题目学生学籍管理系统 目录一.个人简介.二.报告摘要.三.报告目录.四.报告正文. 1.系统需求分析 2.系统总体设计 3.系统详细设计六.总结. 二.报告摘要 ...

  9. C语言课设物资管理系统,C语言课设之物资管理系统.doc

    C语言课设之物资管理系统 C语言课程设计 目 录 1.需求分析: 2.系统总框图: 3.每个模块的设计分析: 4.列出所有定义的函数及说明: 5.举例说明1.2个比较有特点的算法: 6.数据分析.完备 ...

  10. 电影院选票系统(C语言课设)

    这里给到大家介绍一个自己写的C语言课设的代码,代码功能不是很完善,只有很基础的增删改查 题目 :电影院选票系统 功能 :放映厅 ,电影信息的 增删改查,以及排序 系统要求实现以下功能: 1.输入功能: ...

最新文章

  1. leetcode算法题--二进制求和
  2. 权限框架 - shiro 简单入门实例
  3. Spoken English(015)
  4. Android事件分发浅析
  5. 利用机器学习的排名模型,提升你在英雄联盟的排名
  6. PAT 1068. 万绿丛中一点红(20)-乙级
  7. CodeForces - 729D
  8. DiskFileUpload上传文件并获取前端表单数据
  9. 机器学习--digits手写字体
  10. 计算机自动隐藏桌面图标,AutoHideDesktopIcons-定时、自动隐藏桌面图标,让电脑更清爽!...
  11. 国产龙芯笔记本(on 龙芯2F)的使用体验
  12. 爬虫-抖音无水印视频下载
  13. 免费开通量化软件恒生ptrade和讯投qmt
  14. python软件操作步骤_python+pywinauto C/S架构软件基本操作
  15. pandas学习task05变形
  16. 计算机学院运动会解说词,学校运动会解说词30篇
  17. 教程篇(7.0) 04. FortiGate基础架构 二层交换 ❀ Fortinet 网络安全专家 NSE 4
  18. 群体智能的发展现状:AI网络安全现状、新一代AI发展现状
  19. 一个男人写给前女友的话。。。真心哭了
  20. 李佳琦转行成直播一哥,他做对了哪些事?

热门文章

  1. px和毫米之间的转换
  2. 小趣味:js编写斗地主规则(完整代码)
  3. 什么是探索性测试?探索性测试有哪些方法?
  4. 怎么制定合理的开发计划
  5. 全图各省市乡镇数据交流
  6. Chm 文件资源编辑软件
  7. EPSON机械手视觉操作手册
  8. 计算机网络基本原理pdf,自考计算机网络基本原理课程学习指引.pdf
  9. IDEA 解决一直加载Refreshing VCS history
  10. k-平均算法(k-means算法)(k均值算法)例题