DSP

音频引擎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