Legend of Bob: Playing Sound with FMOD
A 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.
No Comments »
RSS feed for comments on this post. TrackBack URL
Leave a comment
You must be logged in to post a comment.