Mar
22
2008

Legend of Bob: Playing Sound with FMOD

FMOD LogoA few month ago I gave up on the idea on using OpenAL for playing sound effect since trying to get MP3s to play with it was getting annoying. A friend recommended whilst in the Student Union to use FMOD, so I switched over and found it did everything I needed, plus there was plenty of documentation and examples.

So here is some basic code for getting audio playing using FMOD, as well as a few additional functions. I’ve only allocated blocks for playing 10 sounds (if more than 10 sounds are attempted to be loaded, LoadSoundByFile() returns -1).

Here is the header for my sound manager.

#ifndef SOUNDMANAGER_H_INCLUDED
#define SOUNDMANAGER_H_INCLUDED

// --- [ libraries ] ------------------------------------------
#pragma comment(lib, "fmodex_vc.lib")

// --- [ includes ] -------------------------------------------
#include <fmod.hpp>

// --- [ definitions ] ----------------------------------------
#define SOUND_LOOP_INFINITE -1
#define MAX_NUM_SOUNDS 10

// --- [ class ] ----------------------------------------------
class SoundManager
{
// Attributes
private
FMOD::System * m_pSystem;
FMOD::Sound * m_pSound[MAX_NUM_SOUNDS];

// Functions
public:
// Constructor
SoundManager();

// Destructor
~SoundManager();

// Load Sound from File
int LoadSoundFromFile( const char * inFilename );

// Free Sound
void FreeSound( const int inSoundId );

// Play Sound
void PlaySound( const int inSoundId );

// Set Position
void SetSoundPosition( const int inSoundId, const int inPositionInMilliseconds );

// Set Loop Count
void SetSoundLoopCount( const int inSoundId, const int inCount );

// Set Loop Points
void SetSoundLoopPoints( const int inSoundId, const int inStartInMilliseconds, const int inEndInMilliseconds );
};

#endif

For background music, I’ve also included code so that the sound can be looped forever, and since not all sounds will be looping from the beginning, I’ve added a function to set where the loop repeats from and begins again. When a sound is not being used anymore, FreeSound() should be called for the id returned by LoadSoundFromFile().

And finally the source file for my sound manager.

// --- [ includes ] -------------------------------------------
#include "SoundManager.h"

// --- [ constructor / destructor ] ---------------------------
SoundManager::SoundManager()
{
for( unsigned int i = 0; i < MAX_NUM_EFFECTS; ++i )
{
m_pSound[i] = 0;
}

// Create FMOD SoundSystem
FMOD::System_Create( &m_pSystem );

// Check FMOD Version
unsigned int fmodVersion;
m_pSystem->getVersion( &fmodVersion );
assert( fmodVersion >= FMOD_VERSION )

// Initialize FMOD SoundSystem
m_pSystem->init(32, FMOD_INIT_NORMAL, 0);
}

SoundManager::~SoundManager()
{
// Free FMOD Sounds
for( unsigned int i = 0; i < MAX_NUM_SOUNDS; ++i )
{
if( m_pSound[i] )
{
m_pSound[i]->release();
}
}

// Free FMOD SoundSystem
if( m_pSystem )
{
m_pSystem->close();
m_pSystem->release();
m_pSystem = 0;
}
}

// --- [ functions ] ------------------------------------------
int SoundManager::LoadSoundFromFile( const char * inFilename )
{
for( int i = 0; i < MAX_NUM_SOUNDS; ++i )
{
if( !m_pSound[i] )
{
m_pSystem->createSound( inFilename, FMOD_SOFTWARE, 0, &m_pSound[i] );
return i;
}
}

return -1;
}

void SoundManager::FreeSound( const int inSoundId )
{
assert( inSoundId >= 0 && inSoundId < MAX_NUM_SOUNDS );

if( m_pSound[inSoundId] )
{
m_pSound[inSoundId]->release();
m_pSound[inSoundId] = 0;
}
}

void SoundManager::PlaySound( const int inSoundId )
{
assert( inSoundId >= 0 && inSoundId < MAX_NUM_SOUNDS );

if( m_pSound[inSoundId] )
{
FMOD::Channel * channel;
m_pSystem->playSound( FMOD_CHANNEL_FREE, m_pSound[inSoundId], false, &channel );
}
}

void SetSoundPosition( const int inSoundId, const int inPositionInMilliseconds )
{
assert( inSoundId >= 0 && inSoundId < MAX_NUM_SOUNDS );

if( m_pSound[inSoundId] )
{
m_pSound[inSoundId]->setPosition( inPositionInMilliseconds, FMOD_TIMEUNIT_MS );
}
}

void SoundManager::SetSoundLoopCount( const int inSoundId, const int inCount )
{
assert( inSoundId >= 0 && inSoundId < MAX_NUM_SOUNDS );

if( m_pSound[inSoundId] )
{
m_pSound[inSoundId]->setLoopCount( inCount );
}
}

void SoundManager::SetSoundLoopPoints( const int inSoundId, const int inStartInMilliseconds, const int inEndInMilliseconds )
{
assert( inSoundId >= 0 && inSoundId < MAX_NUM_SOUNDS );

if( m_pSound[inSoundId] )
{
m_pSound[inSoundId]->setLoopPoints( inStartInMilliseconds, FMOD_TIMEUNIT_MS, inEndInMilliseconds, FMOD_TIMEUNIT_MS );
}
}

All timing in my code is in milliseconds, but it can be changed to another supported FMOD time unit.

Written by Kaluriel in: Code, Legend of Bob, Tutorials | Tags: , , ,

No Comments »

RSS feed for comments on this post. TrackBack URL

Leave a comment

You must be logged in to post a comment.

Theme: TheBuckmaker.com Blog Themes | The best Webhosting Plans, Eigenes Internet Radio