I have a resource manager (World) that loads and hashes sf::SoundBuffer objects into an std::map, and an object factory (Level) that creates an stores Instance objects in an std::vector. All the objects in the game can access the object factory and the resource manager, so can create sf::Sound objects from the buffers that the latter stores.
To test playing sounds I used a dirty kludge:
///Fire projectiles
static ushort reloading = 0;
if(reloading)
reloading--;
else if(input.IsMouseButtonDown(sf::Mouse::Left))
{
other = level->add_instance(INST_PROJECTILE,x,y);
towardsMouse = getDirection(x,y,input.GetMouseX()+level->view.Left,input.GetMouseY()+level->view.Top);
other -> setMotion(10,towardsMouse);
reloading = 15;
static sf::Sound* sound;
sound = new sf::Sound(*level->world->getSoundBuffer(SOUND_GUN));
sound->Play();
}
This works fine, for the first 256 shots fired. Then it stops playing - clearly I have created too many Sound objects without cleaning up:
AL lib : ALc.c:1879: exit(): closing 1 Device
AL lib : ALc.c:1808: alcCloseDevice(): destroying 1 Context(s)
AL lib : ALc.c:1420: alcCloseContext(): destroying 256 Source(s)
Inconsistency detected by ld.so: dl-close.c: 731: _dl_close: Assertion 'map->l_init_called' failed!
I'd sort of hoped that any Sound that doesn't loop would be deleted automatically when it finishes playing. I'm not really sure how sf::Sound objects actually work at a slow level: maybe after starting to play the sound I can delete the handle? Like mutex attributes in pthread.
static sf::Sound* sound;
sound = new sf::Sound(*level->world->getSoundBuffer(SOUND_GUN));
sound->Play();
delete sound;
Nope - deathly silence. Clearly I can't just create a new sound whenever I need one, unless I store them in a container and make sure I delete them when they finish playing. I could try using the same sf::Sound for all the shots fired:
static sf::Sound* sound = new sf::Sound(*level->world->getSoundBuffer(SOUND_GUN));
sound->Play();
But obviously this isn't the best solution, even for the unique Player object doing the firing: depending on the reload speed I may need to be playing the sound twice at the same time, or it sounds really bad!
I've got a few other ideas, like giving the Projectile object an sf::Sound attribute that it plays upon creation and destroys upon destruction, but I'm wondering if anyone knows of a "propre" way of doing this?
Perhaps more importantly, I get that error whether or not I'm creating too many sf::Sounds or not!
Inconsistency detected by ld.so: dl-close.c: 731: _dl_close: Assertion 'map->l_init_called' failed!
If you have any idea why, please let me know!
William