【游戏编程】分享一个FMOD 的编程实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shangdi712/article/details/48348197

           实例代码:点击打开链接

           FMOD 4.44:点击打开链接

           FMOD 4.44 Disigener :点击打开链接

            FMOD是一个非常简单通用的音频引擎,可以在Windows, WinCE, Linux, GameCube Xbox等平台上很好运行.FMOD是一个共享软件,如果不用于商业用途可以免费使用,商业用途需要付费100美金.

           FMOD将它细分在两个API中.他们分别是FSOUND和FMUSIC,所有的MUSIC如:mod、s3m、xm、it、mid、rmi、sgt、fsb 都通过FMUSIC 这个API来播放。FSOUNDAPI是提供给压缩格式使用的,文件一般如:wav,mp3,ogg,raw等这些格式,你都可以通过别的软件进行互相转换。如果你要播放的音乐是像炮弹发射一样的短小的声音,那么你可以将这些声音转换成Sample,Samples将在播放前先解压到内存,而且可以多次播放;如果你要播放的是像背景音乐一样的较长的音乐,你可以得到这个音乐并转化为流,这将导致使用一些CPU和内存,因为文件从磁盘读取然后转成流需要一个过程。同时需要注意一点,在同一时间不能多次播放FMUSIC。

(以上就是关于FMOD在百度上搜集的相关解释)

           然而FMOD虽然有诸多优点,但是网上教程有限,而且,各个版本用法也都不尽相同,所以,给很多初学者带来大量的困难,所以在此,我分享一个FMOD的编程的实例,以帮助希望使用FMOD播放音效的游戏开发者们,但是,由于我的水平有限,我的实例也仅仅只是能播放压缩格式的音频,至于无损格式,我也是在研究中

           我前面写过一个自制的小型引擎,所以,我在这个实例里,将FMOD的使用方法封装成了类,以便集成在我的小型引擎里,如果大家仅仅希望使用这个引擎,完全可以考虑直接运用我这个类,当然,如果大家感觉我的累的功能不够完善,欢迎大家提出来,并且希望大家参与进来帮我修改补充下,我在此感激不尽

我先把代码贴出来,工程我也会上传供下载,然后我的FMOD的版本是FMOD Ex 4.44

运行代码前,大家一定要先在工程里导入包含目录和库目录,右击解决方案的名字,然后属性,在左面的选项卡里选择C++目录

然后在右侧包含文件里添加如下路径:你FOMD安装路径->api文件夹->inc;

之后再库目录里加入如下路径:你的安装路径->api文件夹->lib;

然后点击确定,之后将图上几个文件复制到工程代码文件所在的目录下即可

//Utility.h
#include <iostream>
using namespace std;

#include <fmod.hpp>
#pragma comment(lib,"fmodex_vc.lib")

#include <vector>

//EngineSound.h
#define CEngineSound_H_
#pragma once
class CEngineSound
{
protected:
	FMOD::System * m_pSystem;	//声音系统

	FMOD::Sound     * m_pSound;
	FMOD::Channel   * m_pChannel;
 
	vector<FMOD::Sound*> soundArray;
	vector<FMOD::Channel*> channelArray;

public:
	CEngineSound();
	~CEngineSound();

	//初始化声音系统
	bool initFMod();

	//-------------播放mp3背景音乐-------------
	void LoadStream(const char * fileName);	//使用Stream时,当中途重新播放时,会停止先前的播放而重新播放
	void SetStreamVolume(float volume);		//参数取值范围是0-1,默认是1,最大音量
	void SetStreamPaused(bool state);		//true表示暂停,false表示重开始
	void SetStreamLooping(bool loop);		//true表示循环,false表示不循环
	void PlayStream(bool paused);			//参数为true时,可以在开始播放时暂停,这样就可以更改声音的属性而不会被用户听见,然后取消暂停即可播放
	void StopStream();						//停止一个流的播放
	void ReleaseStream();					//释放

	//-------------播放ogg音效-------------
	void LoadSound(const char * fileName);//使用Sound时,当中途重新播放时,不会停止先前的播放它会又重新开一个channel,这很适用于音效,特别是枪械连发的音效
	void SetSoundVolume(unsigned char id, float volume);//参数2取值范围是0-1,默认是1,最大音量
	void SetSoundPaused(unsigned char id, bool state); //true表示暂停,false表示重开始
	void SetSoundLooping(unsigned char id, bool loop); //true表示循环,false表示不循环
	void StopSound(unsigned char id);
	void ReleaseSound(unsigned char id);
	void PlaySoundEffect(unsigned char id, bool paused);

	//回收资源
	void ReleaseAllSound();

};
#endif

//EngineSound.cpp
#include "Utility.h"
#include "EngineSound.h"

CEngineSound::CEngineSound()
{
	m_pSystem = nullptr;
	m_pSound = nullptr;
	m_pChannel = nullptr;
}

CEngineSound::~CEngineSound()
{
}

bool CEngineSound::initFMod()
{
	FMOD_RESULT    result;			//用来存储函数返回值
	unsigned int   version;			//用来存储版本信息
	int      numdrivers;			//声音驱动器数量
	FMOD_SPEAKERMODE speakermode;	//声音播放硬件模式
	FMOD_CAPS    caps;				//声音系统的能力
	char     name[256];				//名字数组

	FMOD::System_Create(&m_pSystem);//创建声音系统
	
	m_pSystem->getVersion(&version);
	if (version < FMOD_VERSION)
		return false;

	m_pSystem->getNumDrivers(&numdrivers);

	if (numdrivers == 0)
		return false;

	//获取声音播放系统的能力
	m_pSystem->getDriverCaps(0, &caps, 0, &speakermode);

	//设置声音播放器格式
	m_pSystem->setSpeakerMode(speakermode);

	if (caps & FMOD_CAPS_HARDWARE_EMULATED)
	{
		m_pSystem->setDSPBufferSize(1024, 10);
	}
	m_pSystem->getDriverInfo(0, name, 256, 0);

	if (strstr(name, "SigmaTel"))
	{
		m_pSystem->setSoftwareFormat(48000, FMOD_SOUND_FORMAT_PCMFLOAT, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
	}

	result = m_pSystem->init(100, FMOD_INIT_NORMAL, 0);
	if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
	{
		m_pSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
		m_pSystem->init(100, FMOD_INIT_NORMAL, 0);
	}

	return true;
}

void CEngineSound::LoadStream(const char * fileName)
{
	//FMOD_DEFAULT等效于FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE
	m_pSystem->createStream(fileName, 
		FMOD_HARDWARE | FMOD_LOOP_NORMAL | FMOD_2D, 0, &m_pSound);
}
void CEngineSound::SetStreamVolume(float volume)
{
	m_pChannel->setVolume(volume);
}
void CEngineSound::SetStreamPaused(bool state)
{
	m_pChannel->setPaused(state);
}
void CEngineSound::SetStreamLooping(bool loop)
{
	if (loop)
		m_pSound->setMode(FMOD_LOOP_NORMAL);
	else
		m_pSound->setMode(FMOD_LOOP_OFF);
}
void CEngineSound::PlayStream(bool paused)
{
	m_pSystem->playSound(FMOD_CHANNEL_REUSE, m_pSound, paused, &m_pChannel);
}
void CEngineSound::StopStream()
{
	m_pChannel->stop();
}
void CEngineSound::ReleaseStream()
{
	m_pSound->release();
	m_pSound = nullptr;
}



void CEngineSound::LoadSound(const char * fileName)
{
	FMOD::Sound* sound;

	//FMOD_DEFAULT等效于FMOD_LOOP_OFF | FMOD_2D | FMOD_HARDWARE也可以使用FMOD_SOFTWARE实现软件混合
	m_pSystem->createSound(fileName, FMOD_DEFAULT, 0, &sound);

	soundArray.push_back(sound);
	channelArray.push_back(0);
}
void CEngineSound::SetSoundVolume(unsigned char id, float volume)
{
	channelArray[id]->setVolume(volume);
}
void CEngineSound::SetSoundPaused(unsigned char id, bool state)
{
	channelArray[id]->setPaused(state);
}
void CEngineSound::SetSoundLooping(unsigned char id, bool loop)
{
	if (loop)
		soundArray[id]->setMode(FMOD_LOOP_NORMAL);
	else
		soundArray[id]->setMode(FMOD_LOOP_OFF);
}
void CEngineSound::StopSound(unsigned char id)
{
	channelArray[id]->stop();
}
void CEngineSound::ReleaseSound(unsigned char id)
{
	soundArray[id]->release();
	soundArray[id] = nullptr;
	channelArray[id] = 0;
}
void CEngineSound::PlaySoundEffect(unsigned char id, bool paused)
{
	FMOD::Channel* channel;
	m_pSystem->playSound(FMOD_CHANNEL_FREE, soundArray[id], paused, &channel);
	channelArray[id] = channel;
}



void CEngineSound::ReleaseAllSound()
{
	for (vector<FMOD::Sound*>::iterator iter = soundArray.begin();
		iter != soundArray.end(); ++iter)
	{
		(*iter)->release();
		(*iter) = nullptr;
	}
	soundArray.clear();
	channelArray.clear();
}


//main.cpp
#include "Utility.h"
#include "EngineSound.h"

int main()
{
	CEngineSound * pSound = new CEngineSound();
	pSound->initFMod();

	//---------------播放mp3背景音乐------------------
	pSound->LoadStream("res\\music\\SayGoodBye.mp3");
	pSound->SetStreamVolume(1.0f);
	pSound->SetStreamLooping(true);
	pSound->PlayStream(false);


	//---------------播放ogg音效------------------
	pSound->LoadSound("res\\music\\boss_explode.ogg");
	pSound->SetSoundVolume(0, 1.0f);
	pSound->SetSoundLooping(0, false);
	pSound->PlaySoundEffect(0, false);


	//pSound->ReleaseAllSound();
	system("pause");
	return 0;

}



猜你喜欢

转载自blog.csdn.net/shangdi712/article/details/48348197