Tutorial – how to use FMOD with C++

Note: This was written a while ago, therefore the quality is not up to standards, although the tutorial is still valid.

Hi guys. In this tutorial I am going to teach you how to implement the sound system called, FMOD :Β http://www.fmod.org/

Downloading:

Go to the url:Β http://www.fmod.org/fmod-downloads.htmlΒ and select your OS, this tutorial will be based on the windows platform. You will be given an installation file (exe), install it normally. If you choose to change the installation path you should note it down, as you’ll need it later on. For FMOD to work properly, you must do the following.

Installation

Include Directories:

  • %FMOD ROOT%\FMOD Programmers API Windows\api\inc

Library Directories:

  • %FMOD ROOT%\FMOD Programmers API Windows\api\lib

Copying: Then you should also copy these dll’s to your project output folder:

  • fmodex.dll
  • fmodex64.dll
  • fmodexL.dll
  • fmodexL64.dll

Linking: You should link this library:

  • fmodex_vc.lib

Initializing FMOD

To gain access to FMOD, you must include:


#include "fmod.hpp"
#include "fmod_errors.h" // Only if you want error checking

Lets create a class called SoundSystemClass shall we!

class SoundSystemClass
{
 // Pointer to the FMOD instance
 FMOD::System *m_pSystem;
 SoundSystemClass () {}
}

And for the simplicity, I typedef the default fmod sound class to my own name, as following:

typedef FMOD::Sound* SoundClass;

To initialize FMod, we create a contructor for the class, error checking is still minimal as that will come later.

SoundSystemClass ()
 {
    if (FMOD::System_Create(&m_pSystem) != FMOD_OK)
    {
       // Report Error
       return;
    }

    int driverCount = 0;
    m_pSystem->getNumDrivers(&driverCount);

    if (driverCount == 0)
    {
       // Report Error
       return;
    }

    // Initialize our Instance with 36 Channels
    m_pSystem->init(36, FMOD_INIT_NORMAL, NULL);
 }

When create FMod, you get a pointer to the instance as a result, which you will be able to use later, and as a security check, we checked that the current pc actually has a sound driver. To initialize this pointer, you call the method, ->init(..), which requires the number of channels, some flags, and some extra driver information if needed. We call the ->init(…), with 36 channels, which can be increased or decreased to your choice, each channel can hold ONE sound, so it all depends on your game, and we pass the normal initialization flag. To create a sound, we create a new method called createSound(…), which takes a pointer to our typedef SoundClass, and the sound file path:


void createSound(SoundClass *pSound, const char* pFile)
 {
    m_pSystem->createSound(pFile, FMOD_HARDWARE, 0, pSound);
 }

When we create a new sound with FMod, we specify the file path, could be any, and the creation flags, we specified HARDWARE, should be fine for now, and some info for the sound itself, and of course, a pointer in return. To play the sound, we need to specify the channel, and we can send some flags as well, therefore, we create the method called playSound(…):


void playSound(SoundClass pSound, bool bLoop = false)
 {
    if (!bLoop)
       pSound->setMode(FMOD_LOOP_OFF);
    else
    {
       pSound->setMode(FMOD_LOOP_NORMAL);
       pSound->setLoopCount(-1);
    }

    m_pSystem->playSound(FMOD_CHANNEL_FREE, pSound, false, 0);
 }

In this method, we have a boolean called bLoop, which is an option the user can take, weather the sound should loop or not. If not, we simply set the Mod FMOD_LOOP_OFF from the sound pointer (Simple, right?), but if the user chooses to loop the sound, we set the mode FMOD_LOOP_NORMAL and set the loop count to -1, which means unlimited, you can play with it if you want. And finally, we create a method for releasing the sound, called releaseSound(…), which takes a pointer to the sound.


void releaseSound(SoundClass pSound)
 {
    pSound->release();
 }

Example of usage of class:

// Initialize our sound system
SoundSystemClass sound;
sound.Initialize();

// Create a sample sound
SoundClass soundSample;
sound.createSound(&soundSample, "C:\\mysound.wav");

// Play the sound, with loop mode
sound.playSound(soundSample, true);

// Do something meanwhile...

// Release the sound
sound.releaseSound(soundSample);

Sound System Class code:

typedef FMOD::Sound* SoundClass;

class SoundSystemClass
{
    // Pointer to the FMOD instance
    FMOD::System *m_pSystem;

    SoundSystemClass ()
    {
       if (FMOD::System_Create(&m_pSystem) != FMOD_OK)
       {
          // Report Error
          return;
       }

       int driverCount = 0;
       m_pSystem->getNumDrivers(&driverCount);

       if (driverCount == 0)
       {
          // Report Error
          return;
       }

       // Initialize our Instance with 36 Channels
       m_pSystem->init(36, FMOD_INIT_NORMAL, NULL);
    }

    void createSound(SoundClass *pSound, const char* pFile)
    {
       m_pSystem->createSound(pFile, FMOD_HARDWARE, 0, pSound);
    }

    void playSound(SoundClass pSound, bool bLoop = false)
    {
       if (!bLoop)
          pSound->setMode(FMOD_LOOP_OFF);
       else
       {
          pSound->setMode(FMOD_LOOP_NORMAL);
          pSound->setLoopCount(-1);
       }

       m_pSystem->playSound(FMOD_CHANNEL_FREE, pSound, false, 0);
    }

    void releaseSound(SoundClass pSound)
    {
       pSound->release();
    }
};

Hope you enjoyed this tutorial. Feel free to post some advice on how to improve, though this is my first tutorial I have ever made. πŸ™‚

Advertisements

Cuboid Engine – SSAO – Scripting

In a nutshell:

  • Fixed SSAO with new pipeline, nice results
  • Improved scripting, plus CDK Scripting IDE

SSAO:

So as I mentioned in the previous posts, I have changed my engine architecture, mostly GPU side, approaching the deferred way. What’s left?

  • Lighting (Well the correct way :))

Screenshot of SSAO working: (The SSAO is visible where there is contact between the plane and the cube, left to the shadows)

Image

The SSAO buffer, the artifacts around the plane and on the top of the cube are created because there is simply nothing around them, which I haven’t programmed CDK to handle, ohh and in the bottom, it seems like there are some falso occlusions, why?, I really don’t know yet, but that day will come :):

Image

CDK Scripting – Scripting:

Implemented my actor system (just started), structure:

  • Actor->
  1. Mesh pointer :: a pointer to the mesh which the script can access, this will change though
  2. Controller :: the controller is a pathway to the script object, and yes, the scripting is object oriented, it’s actually almost C#!

And the good thing is that, when calling actorx.update (Each actor HAS to have an update function, inherited from it’s master), the fps loss is around 1, with ~20 actors! But the functions are almost empty :)…

Changes to the Scripting IDE:

  • Proper visualization of errors and warnings, like:
    In file x
    Line x
    Code type
    Details
  • Fixed bug of duplication of errors and warnings.
  • Fixed bug of icon creation error
  • Automatic solution refreshing when compiling, so you only have to touch the candy! πŸ™‚

Well, i guess that’s it for now, see you next time!

Happy day today!

I just improved my framerate with 10-15 fps! πŸ™‚

I made my own small IDE for Cuboid Engine, called CDK(Cuboid Development Kit) Scripting IDE. Screenshot:

Image

And it uses C#, which can communicate with c++, live really fast, so it will become Cuboid’s engine scripting language. (The communication works, now I just need to add.)

Cuboid Engine – Port to Release Mode – Deferred Rendering

Hello once again!

Update:

For now my PC has appeared to be stable, so I’ll just let it be that way for now.

Engine now runs again, on new pc OS (Required a lot of work!)

New:

The engine has been ported to the release mode which is a huge step for me πŸ™‚

The engine has an improved architecture now, as I’m approaching deferred lighting more and more, so now I’m only rendering the scene 2-3 times max, which includes:

  • GBuffer Pass (Albedo, Normals, Depth, Base Lighting via 4 Multi-Render Targets)
  • Glow Map Pass

The material system has the deferred shader integrated, and the only thing you modify is the albedo output and the vertex shader when writing materials, so it’s flexible.

In the few past days, I’ve just made a very small playable demo (in the release mode), which was alright:

PS. Though you can’t see it, stars are kinda flying past you, which creates this cool effect πŸ™‚

Another Update:

I’m moving to Denmark!