音频引擎FMOD学习记录02:控制暂停/继续,调节音量,设置声效
2019-07-13 17:26发布
生成海报
这是本系列的第二篇,本文针对上一篇的入门示例进行了简单扩展。
入门示例(第一篇)戳这里http://blog.csdn.net/fengyhack/article/details/43318575
扩展内容包括:
1.控制暂停/继续
2.调节音量大小
3.激活/关闭声音特效
首先贴几张运行时截图吧
初始状态:播放中,音量50%,未开启任何特效
按下按键'P'暂停播放
暂停状态时再按'P'继续播放
每按一次'A'/'B'音量增加/减少10%,按4次'A'增加到90%
按下‘E'开启回声效果,按下'D'开启扭曲(类似“破音”)效果
其他特效包括OSCILLATOR,FLANGE, CHORUS, CONVOLUTIONREVERB等
本示例只提供ECHO和DISTORTION两种,其他类似。
当前状态:播放中,音量40%,已开启回声与扭曲效果
如需取消刚才设置的特效,只需再次按下'E'或'D'
按下'Q'键,退出播放循环
下面将源代码贴上来然后做一个简单分析(代码注释比较详细呢^_^)
#include // FMOD_...
#include
#include // system()
#include // isprint()
#pragma comment(lib,"fmod_vc.lib") // FMOD_xxx...
#pragma warning(disable:4996)
int main(void)
{
/*
下述的双冒号::表示全局作用域
这样做是为了区分系统system与FMOD::System system
参数color: 前景 {MOD}/背景 {MOD}
参数title: 标题
*/
::system("color 2e");
::system("title Simple FMOD demo CREATED by fengyhack");
const char* fileName = "1.mp3";
float volume = 0.5f; // 初始音量50%
FMOD::System* system = NULL;
FMOD::Sound* sound = NULL;
FMOD::Channel* channel = NULL;
FMOD::DSP* dspEcho = NULL; // 回声
FMOD::DSP* dspDisto = NULL; // 扭曲
System_Create(&system);
system->init(10, FMOD_INIT_NORMAL, NULL); // 第一个参数10表示最多10个混音
system->createSound(fileName, FMOD_LOOP_NORMAL | FMOD_2D, NULL, &sound);
system->createDSPByType(FMOD_DSP_TYPE_ECHO, &dspEcho);
system->createDSPByType(FMOD_DSP_TYPE_DISTORTION, &dspDisto);
/*
为什么在初步设置前先不要播放声音?
下面的playSound()函数第3个参数true表示"暂停"状态
在设置完毕后再恢复"播放"状态,这种设置是必要的!!!
如果不这样做,那么在设置自定义状态之前
系统就已经按照默认状态开始播放了(这不是我们想要的)
*/
system->playSound(sound, NULL, true, &channel);
// 现在设置初始状态如音量等
channel->setVolume(volume);
dspEcho->setBypass(true);
dspDisto->setBypass(true);
channel->addDSP(0, dspEcho);
channel->addDSP(0, dspDisto);
/*
在设置了音量、添加声效之后再打开"播放"开关
setPaused(false)表示取消刚才的"暂停"状态
这样系统一开始播放时就是按照我们之前做的自定义设置来进行的
*/
channel->setPaused(false);
char key = 0;
bool paused = false;
bool dsp_echo = false;
bool dsp_disto = false;
while (true)
{
/*
这个循环是为了让主函数永不结束(除非输入'Q'键)
这样FMOD就有机会继续执行任务(播放声音)
否则主函数会继续执行下一语句,直接退出
实际情况不应该是这样,这里仅仅作为一个示例罢了
实际情况应该是有一个前台任务在执行,在后台播放声音
*/
// !!!!!!!!!! 请务必在每一帧(frmae)中执行update()
system->update();
::system("cls"); // 清屏
printf("------------ CMMOAND ------------
");
if (paused) // 暂停或继续
{
printf("| P/p: resume
");
}
else
{
printf("| P/p: pause
");
}
if (dsp_echo) // 回声效果
{
printf("| E/e: disable echo effect
");
}
else
{
printf("| E/e: enable echo effect
");
}
if (dsp_disto) // 扭曲("破音")
{
printf("| D/d: disable distortion
");
}
else
{
printf("| D/d: enable distortion
");
}
printf("| ---- Sound vloume: %.2f
", volume);
printf("| A/a: volume +0.1 (max 1.0)
"); // 音量增10%
printf("| B/b: vloume -0.1 (min 0.1)
"); // 音量减10%
printf("| Q/q: stop and quit
"); // 退出
printf("---------------------------------
");
printf("Input your command:");
key = getchar();
if (isprint(key)) // 是否为可打印字符
{
/*
再次执行getchar()以“吃掉”输入字符之后的回车符
例如输入 X
那么key=X然后吃掉
如果不这么做,下一次循环执行key=getchar()
结果为key= ('
')
*/
getchar();
}
if (key == 'q' || key == 'Q') break;
switch (key)
{
case 'P':
case 'p':
/*
如何设置get和set的先后顺序?
与update()有什么关系?
*/
channel->setPaused(!paused);
channel->getPaused(&paused);
break;
case 'E':
case 'e':
dspEcho->getBypass(&dsp_echo);
dspEcho->setBypass(!dsp_echo);
break;
case 'D':
case 'd':
dspDisto->getBypass(&dsp_disto);
dspDisto->setBypass(!dsp_disto);
break;
case 'A':
case 'a':
volume += 0.1f;
if (volume > 1.0) volume = 1.0f;
channel->setVolume(volume);
break;
case 'B':
case 'b':
volume -= 0.1f;
if (volume < 0.1) volume = 0.1f;
channel->setVolume(volume);
break;
default:
break;
}
}
sound->release();
system->close();
::system("cls");
::system("color 2f");
printf("====================================
");
printf("= Copyleft (LF) 2015, fengyhack
");
printf("= For more details, see
");
printf("= http://blog.csdn.net/fengyhack
");
printf("= Or you can contact me by
");
printf("= Email: fengyhack@163.com
");
printf("====================================
");
printf("Press ENTER to exit the program...");
getchar();
return 0;
}
注意!!!
因为我们在程序中创建了一个FMOD::System类型变量*system
二这个变量的名字取得“不好”,因为它和系统函数system()冲突了
为了解决这个麻烦,最好将变量取为别的名字,例如fmodSystem等
其次,代码中的输出提示为英文,注释为中文,这种风格也不太好
但是注释是新手写给新手看的,因此采用中文(说白了就是鄙人英文不太好||$_$)
本文原创,博文地址
http://blog.csdn.net/fengyhack/article/details/43375857
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮