I've started coding a new game project and I've implemented Ogre for the graphics rendering and begun thinking about the audio side of things.
I was considering using the SFML audio component for implementing audio. It is cross platform and can handle streaming music from the file or playing sounds loaded into memory from a buffer.
My initial thoughts were along the line of creating an audio manager class that can load all the relevant sounds into memory and then just be able to play them by reference when required. My concern there was the potential memory use of having a whole lot of sounds loaded into memory.
This is the code I came up with as a very rough test of what I was thinking. Obviously it would need to be improved a lot but it does seem to work.
#include <vector>
#include <string>
#include <iostream>
#include <unistd.h>
#include <SFML/Audio.hpp>
class gameSound
{
public:
gameSound();
~gameSound();
bool loadSound(std::string filename);
std::string name;
sf::SoundBuffer buffer;
sf::Sound sound;
};
gameSound::gameSound(){}
gameSound::~gameSound(){}
bool gameSound::loadSound(std::string filename) {
if(!buffer.loadFromFile(filename))
return false;
sound.setBuffer(buffer);
return true;
}
class SoundManager
{
public:
SoundManager();
~SoundManager();
void PlaySoundByName(std::string name);
void AddSound(gameSound* snd);
std::vector<gameSound*> sounds;
};
SoundManager::SoundManager(){}
SoundManager::~SoundManager(){
while(!sounds.empty())
{
sounds.pop_back();
}
}
void SoundManager::AddSound(gameSound* snd) {
sounds.push_back(snd);
std::cout << "gameSound added with name: " << snd->name << " total sounds : " << sounds.size() << std::endl;
}
void SoundManager::PlaySoundByName(std::string name) {
for(std::vector<int>::size_type i = 0; i != sounds.size(); i++) {
if(sounds[i]->name == name) {
std::cout << "Match found for " << name << std::endl;
sounds[i]->sound.play();
}
}
}
int main()
{
SoundManager* smgr = new SoundManager();
gameSound* s1 = new gameSound();
s1->loadSound("sound.ogg");
s1->name = "Sound";
gameSound* s2 = new gameSound();
s2->loadSound("alarm.ogg");
s2->name = "Alarm";
gameSound* s3 = new gameSound();
s3->loadSound("dog-grunt.ogg");
s3->name = "DogGrunt";
smgr->AddSound(s1);
smgr->AddSound(s2);
smgr->AddSound(s3);
smgr->PlaySoundByName("DogGrunt");
sleep(2);
smgr->PlaySoundByName("Alarm");
sleep(2);
return 0;
}
I know with most systems these days, especially gaming systems, there is usually plenty of memory so it might not be an issue. I was considering implementing a way to load the most important sounds into memory for instant access and then have less common sounds loaded and freed from memory as they are required.
I am interested to know how others have approached the handling of audio required for a game and if I am on the right track.