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

Author Topic: Sounds stop playing after a while  (Read 4063 times)

0 Members and 2 Guests are viewing this topic.

Felheart

  • Newbie
  • *
  • Posts: 23
    • View Profile
Sounds stop playing after a while
« on: November 05, 2011, 07:20:11 pm »
Hi,

when I spawn lots of sounds, after a time they stop playing.

I load a sound from a file into a SoundBuffer once (in the constructor of the game).
Then everytime I need to play an instance of that sound I create a new sound instance (with the SoundBuffer from the beginning as parameter).
I immediately call Play on the instance without keeping a reference to it anywhere.

This works for a few seconds/minutes.
After a while no more sounds are being played.
The time until this happens varies, when i create more sound instances the time is shorter.

Am I doing anything wrong ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Sounds stop playing after a while
« Reply #1 on: November 05, 2011, 07:32:40 pm »
There's an internal limit on the number of sound that you can create. If you never delete unused sounds then you have a leak. Fix this and your problem will be solved.
Laurent Gomila - SFML developer

Felheart

  • Newbie
  • *
  • Posts: 23
    • View Profile
Sounds stop playing after a while
« Reply #2 on: November 05, 2011, 07:37:17 pm »
I was under the impression that once the garbage collector starts, it calls the Dispose method of every object it deletes.

I can confirm that the garbage collector runs at least every few seconds in my game

Do I have to call Dispose manually on every SFML-object ??

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Sounds stop playing after a while
« Reply #3 on: November 05, 2011, 07:45:57 pm »
The "default" language here is C++, you must say it explicitely if you use another one ;)

Things are of course very different in .Net, the GC is indeed supposed to properly destroy objects that are not used anymore. However the GC is not supposed to know if a sound is playing or not. So if all your sounds are always played completely, I suspect that the GC never destroys them.

Could you provide a complete and minimal example that reproduces the problem?
Laurent Gomila - SFML developer

Felheart

  • Newbie
  • *
  • Posts: 23
    • View Profile
Sounds stop playing after a while
« Reply #4 on: November 05, 2011, 08:16:16 pm »
I found the problem. :D
I forced the GC to run every 10th frame, but only on the 0th collection.
But most of the sounds belonged to the 2nd or 3rd generation of objects!

In my game every rocket has its explosion sound. But a rocket often lives longer than 10frames, so it gets promoted to a higher object generation.

And it can take the GC quite a while to decide that it's now time for a generation2 or 3 cleanup.

I'm sorry to have wasted your time :(
But thanks for your help (and the fast replys!)

Felheart

  • Newbie
  • *
  • Posts: 23
    • View Profile
Sounds stop playing after a while
« Reply #5 on: November 06, 2011, 08:17:51 pm »
Now that I have identified the problem, I thought about various ways to resolve it. But I really don't know what the best method is.
So I'm seeking advice here :)

The problem(as already said) is that sounds play too long and therefore get promoted to higher generations where they are not disposed in time to make place for new sound instances.
Thats why the internal Sound counter in SFML rises and doesn't decrease (fast enough) even though no more sounds are played.

Method 1:
Run the GC more often and on all generations.
But it takes time and introduces a bug and unnecessary overhead!

Method 2: (what I'm currently doing)
I have a static class that accepts "IDisposable" objects and a time.
When the time is up the class calls .Dispose(); on the object to free its resources (hence decreasing the sound counter).
The class has it's own low-priority background thread to carry out its task.

So everytime I need a explosion sound I do the following:
Sound s = new Sound(...);
ObjectDestroyer.RegisterDestruction(s, s.SoundBuffer.Duration);


Is there a better way that I'm overlooking?
I don't like the idea to have just another background thread besides the GC that only collects garbage...

Isn't there a "event" like OnSoundFinishedPlaying that I can register for?

How would you handle this situation Laurent ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Sounds stop playing after a while
« Reply #6 on: November 06, 2011, 11:37:15 pm »
Quote
Is there a better way that I'm overlooking?

Keep sounds in a list, and when you want to play a new one, reuse stopped sounds from the list instead of creating new ones.

Quote
Isn't there a "event" like OnSoundFinishedPlaying that I can register for?

Unfortunately not.
Laurent Gomila - SFML developer