Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to handle many sounds simultaneously?  (Read 9045 times)

0 Members and 1 Guest are viewing this topic.

ingwik

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
How to handle many sounds simultaneously?
« on: January 06, 2012, 07:30:13 pm »
I have a general question about handling sounds in SFML games. My first thoughts about it began when I made a small game/test bed with a tank that was shooting a lot of bullets, actually the idea was to always have about 5 bullets in the air all the time. I have two buffers and two sounds, one for each buffer. When I hit the space key I shoot a grenade with my tank and a shoot-sound is heard. It works just perfect but that happens among the events in the program.

Further down inside the game loop, I have a code that check if the grenade has hit a wall and if so; the grenade disappears and another explosion sound, connected to the second soundbuffer, is supposed to be heard by this code:
Code: [Select]
explosionsound.Play();    
This doesn't work, instead, a buzzing sound as from a bug is heard so I assume it means that the sound is re-started over and over again, 60 times/sec and that is the reason for the peculiar sound.

Another solution to that problem that I found in the forum is adding a check:
Code: [Select]
explosionsound.Play();
while(explosionsound.GetStatus() == sf::Sound::Status::Playing) {}


Now, it explodes, but it continues to explode over and over again, sounds like a loop even though I haven't made it looping and keeps sounding even if I only shoot a single shot. And the game freeze to a halt. Something goes wrong when putting the Play() commando inside the game loop, compared to connecting it to an event where everything works as expected. It's obvvious that I'm doing something wrong when I try to play these sounds inside the game loop.

This made me wonder, and I have read through a lot of different solution in the forum; what is the best way to handle multiple explosion sounds in SFML?

Solution one:
I have one sound buffer with the explosion sound and then I make 20 sounds, seems that no more than that should be heard at the same time anyway. I have an iterator that check where I am 1-20 and if the game plays a sopund I just check if a sound is playing or not with, for instance sound number 10:
Code: [Select]
if(explosionsound10.GetStatus() != sf::Sound::Status::Playing)
 { explosionsound10.Play();}

A safe but cluttered way with no memory leaks.

Solution two
I use new and delete. I have the same buffer created but instead, I make a new sound each time I need to play the sound of an explosion.
Code: [Select]
sf::Sound *explosionsound10 = new sf::Sound(soundbuffer_with_explosionsoundfile);
 explosionsound10->Play();
 while(explosionsound10->GetStatus() == sf::Sound::Status::Playing) {}


I keep track over the amont of sounds created and when the game ends, I delete all created sounds to avoid memory leaks. One problem with this is that I think SFML can hold 512 sounds, and I assume that means trouble if more than 512 grenades are shot during a gaming session.

Finally, is there a third solution that I haven't thought about? How are other game creators handling many sounds played simultaneously inside the game loop?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
How to handle many sounds simultaneously?
« Reply #1 on: January 06, 2012, 07:45:34 pm »
I have an std::queue (or std::list if I need more features than just FIFO) with sf::Sound as value type. Not pointers to sf::Sound!

Every time a sound is played, I push it to the queue. Also, I pop the elements at the queue front if they have stopped playing, i.e. GetStatus() returns sf::Sound::Stopped. And make sure you first push the sound and then start playing it, because I prefer not to take assumptions about copy semantics of playing sounds.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
How to handle many sounds simultaneously?
« Reply #2 on: January 06, 2012, 07:59:40 pm »
That approach is interesting, however it has one flaw (unless you check all elements):

If you've got a sound playing 5 seconds and x sounds playing for 1 second, the 5 second sound will keep all sounds alive, even if they're no longer playing - till it stops too.

I just added an array of sf::Sound and iterate over it, the first source that's not playing, get's the soundbuffer set and is started. If none is free, the sound playback request is dropped.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
How to handle many sounds simultaneously?
« Reply #3 on: January 06, 2012, 08:26:44 pm »
True, but you have multiple possibilities to address this issue. Apart from the one you mentioned, you can hold a separate queue for each sound type, or sort the container according to remaining times.

Anyway, it's more a theoretical problem when a sound remains some seconds unused, as long as every sound is eventually destroyed. So, I wouldn't spend too much time and write complicated code just to silence the conscience ;)

By the way, I recommend not to use raw arrays. Use std::array for fixed-size arrays, it offers an STL interface as well as debug checks, for zero costs in release mode. And for resizable arrays, use any other container...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything