FMOD

    技术2022-05-18  16

    FMOD是一个非常简单通用的音频引擎,可以在Windows, WinCE, Linux, GameCube Xbox等平台上很好运行.FMOD是一个共享软件,如果不用于商业用途可以免费使用,商业用途需要付费100美金.下载后将fmod.dllfmodvc.lib加入你的工程中.并引用头文件fmod.h

    在使用fmod播入音乐之前,首先要初始化,代码如下:

    FSOUND_Init(44100,32,0);

    第一个参数为音乐输出的rate,单位为赫兹,在这里我们设置为44100.

    第二个参数为设置最大的通道数量 

    第三个参数,可以指定一些标识,如果我们想的话.这里暂时置它为0.

    好了,现在我们准备开始播放音乐了,FMOD到底支持什么样的音乐格式呢?歌曲,采样或是文件流(song,sample and stream)?

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

     

    FMUSIC

    FMUSIC播放需要一个handle,看如下代码:

    handle = FMUSIC_LoadSong("YourFileName");

    FMUSIC_PlaySong(handle);

    设置音量 

    FMUSIC_SetMasterVolume(handle,256);

    256是最高音,0表示静音 

    暂停音乐 

    FMUSIC_SetPaused(handle,true);

    FMUSIC_SetPaused(handle,false);

    循环播放 

    FMUSIC_SetLooping(handle,true);

    停止音乐 

    FMUSIC_StopSong(handle);

    free内存 

    FMUSIC_FreeSong(handle);

     

    一个例子:

    #include <conio.h>#include "inc/fmod.h"

    FMUSIC_MODULE* handle;

    int main (){ // init FMOD sound system FSOUND_Init (44100, 32, 0);

    // load song handle=FMUSIC_LoadSong ("canyon.mid");

    // play song only once // when you want to play a midi file you have to disable looping // BEFORE playing the song else this command has no effect! FMUSIC_SetLooping (handle, false);

    // play song FMUSIC_PlaySong (handle);

    // wait until the users hits a key to end the app while (!_kbhit()) { }

    //clean up FMUSIC_FreeSong (handle); FSOUND_Close();}

     

    FSOUND 

    得到FSOUND的句柄:

    handle = FSOUND_Sample_Load(0,"yourFileName",0,0,0);

    FSOUND_PlaySound(0,handle);

    这些音效在播放前将被载入内存,所以可能需要一点点时间.

    第二行命令的第一个参数是播放时使用的通道.

    设置音量 

    FSOUND_SetVolume(handle,255);

    255为最大音量,0表示静音 

    暂停音乐 

    FSOUND_SetPaused(handle,true);

    FSOUND_SetPaused(handle,false);

    停止音乐

    FSOUND_StopSound (handle);

    清除内存

    FSOUND_Sample_Free(handle);

     

     

     

    看一个例子:

    #include <conio.h>#include "inc/fmod.h"

    FSOUND_SAMPLE* handle;

    int main (){

     // init FMOD sound system FSOUND_Init (44100, 32, 0);

    // load and play sample handle=FSOUND_Sample_Load (0,"sample.mp3",0, 0, 0); FSOUND_PlaySound (0,handle);

    // wait until the users hits a key to end the app while (!_kbhit()) { }

    // clean up FSOUND_Sample_Free (handle); FSOUND_Close();}

     

     

    Streams

    得到Stream句柄

    handle=FSOUND_Stream_Open("YourFileName",0, 0, 0);FSOUND_Stream_Play (0,handle);

    停止音乐

    FSOUND_Stream_Stop(handle);

    清除

    FSOUND_Stream_Close(handle);

    一个例子:

    #include <conio.h>

    #include "inc/fmod.h"

    FSOUND_STREAM* handle;

    void main (){ //init FMOD sound system FSOUND_Init (44100, 32, 0);

    //load and play sample handle=FSOUND_Stream_Open("sample.mp3",0, 0, 0); FSOUND_Stream_Play (0,handle);

    //wait until the users hits a key to end the app while (!_kbhit()) { }

    //clean up FSOUND_Stream_Close(handle); FSOUND_Close();}

     

    一个fmod应用程序,他首先要加上以下头文件

    #include "http://www.cnblogs.com/api/inc/fmod.hpp"

    #include "http://www.cnblogs.com/api/inc/fmod_errors.h"

    #include <windows.h>

    #include <stdio.h>

    #include <conio.h>

    然后定义声音系统(FMOD::System)、声音(FMOD::Sound)、声道(FMOD::Channel)、声音出现的位置(FMOD_VECTOR)、一个用于判断的结果(FMOD_RESULT)这几个变量。通常情况下还要定一个版本的参数用于检查当前版本是否过时。例如:

        FMOD::System    *system;

        FMOD::Sound     *sound1, *sound2, *sound3;

        FMOD::Channel   *channel1 = 0, *channel2 = 0, *channel3 = 0;

        FMOD_RESULT     result;

        FMOD_VECTOR     listenerpos  = { 0.0f, 0.0f, -1.0f * DISTANCEFACTOR };

    unsigned int    version;//定义版本的变量

    定义好变量之后,就开始编写我们需要的声音资源。下面是一般的步骤:

    1. 创建FMOD系统

    APIFMOD_RESULT System_Create( FMOD::System ** system);

    程序中:result = FMOD::System_Create(&system);

    参数为指向系统变量指针的指针;

    如果创建系统变量成功,就返回FMOD_OK;没有成功就返回FMOD_RESULT中的任意一项。

    2. 检查当前版本是否过时

    APIFMOD_RESULT System::getVersion( unsigned int * version);

    程序中:result = system->getVersion(&version);

    参数为指向版本变量的指针;

    如果创建版本变量成功,就返回FMOD_OK;没有成功就返回FMOD_RESULT中的任意一项。

    3.  初始化系统和声音设备

    必须在FMOD::System_Creat之后,所有用户代码之前就要执行。

    APIFMOD_RESULT System::init( int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata);

    程序中:result = system->init(100, FMOD_INIT_NORMAL, 0);

    maxchannels:FMOD中最大的声道数

    FMOD_INITFLAGS

    FMOD_OUTPUTTYPE:输出查检

    如果初始化成功,就返回FMOD_OK;没有成功就返回FMOD_RESULT中的任意一项。

    4. 开始创建自己需要的声音

    APIFMOD_RESULT System::createSound(const char * name_or_data, FMOD_MODE mode,

                                    FMOD_CREATESOUNDEXINFO *exinfo, FMOD::Sound ** sound);

    程序中:result = system->createSound("../media/drumloop.wav", FMOD_SOFTWARE | FMOD_3D, 0, &sound1);

    name_or_data:声音资源文件名或者URL

    mode:打开声音的模式。

    FMOD_CREATESOUNDEXINFO:希望用户提供个多信息。一般设为0

    FMOD::Sound:指向声音资源变量指针的指针

    5.    设置声音可听见的最小和最远距离

    APISound::set3DMinMaxDistance(float min, float max)

    程序中:sound1->set3DMinMaxDistance(2.0f * DISTANCEFACTOR, 10000.0f * DISTANCEFACTOR);

    min: 最小距离

    max: 最大距离

    6.    开始播放音乐

    APIFMOD_RESULT System::playSound(FMOD_CHANNELINDEX channelid,FMOD::Sound *sound,

    bool paused, FMOD::Channel **channel);

    程序中:result = system->playSound(FMOD_CHANNEL_FREE, sound1, true, &channel                   1);

    FMOD_CHANNELINDEX 得到空闲的声道

    FMOD::Sound 之前定义好的声音变量

    paused 事后停止

    FMOD::Channel 得到的声道的指针

    7.    设置声道的位置以及速度

    APIFMOD_RESULT Channel::set3DAttributes(const FMOD_VECTOR * pos, const FMOD_VECTOR * vel); 

        程序中:result = channel1->set3DAttributes(&pos, &vel);

         pos:声道位置

         vel:声道速度

    8.    得到当前可得到的2d3d的声道数目

    APIFMOD_RESULT System::getHardwareChannels(int *num2d,int *num3d,int*total);

    程序中:result = system->getHardwareChannels(&num2d, &num3d, 0);

    num2d:可以混合3d的数目

    num3d:可以混合2d的数目

    totaltotal = num3d + num2d

    9.    更新3d的位置速度和方向

    APIFMOD_RESULT System::set3DListenerAttributes(int listener, const FMOD_VECTOR *pos,

          const FMOD_VECTOR *vel, const FMOD_VECTOR *forward,const FMOD_VECTOR *up);

    程序中:result=system->set3DListenerAttributes(0,&listenerpos, &vel, &forward, &up);

    listener:如果环境中只有一个听者,则设置为0

    pos:听者的位置

    vel :从声音的起始位置到达听者耳朵时,每一秒的位移

    forward :听者前方的方向

    up:听者上方的方向

    接着就是一个循环更新以及用户自己的键盘响应操作了。该操作是在一个do..while或者while循环中完成的。例如:

    do

    {   //通过函数kbhit()得到键盘响应消息;然后通过getch()得到我们具体要相应的哪个键

           if (kbhit())

            {

                key = getch();

                if (key == '1')

                {   //根据得到的键,响应该键的响应函数

                    bool paused;

                    channel1->getPaused(&paused);

                    channel1->setPaused(!paused);

                }

             }

    //更新听者

    ……

    //更新系统

    system->update();

    //程序中自规定50ms更新一次,所以要sleep50ms;又因为是从0开始计时的,所以要减去1

            Sleep(INTERFACE_UPDATETIME - 1);

    } while (key != 27);

    最后逐一释放之前创建的声音和系统

         result = sound1->release();//释放声音资源

         result = system->close();//先将系统关闭

         result = system->release();//然后释放自己

    其实通过这一个例子;就可以总结出,只要是创建任何东西(例如创建系统、声音、更新3d)、初始化、开始播放、释放自己等API都是系统的接口;而设置声音的属性(位置、速度、是否停止等)是由声道变量提供的API接口的。


    最新回复(0)