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

Author Topic: Reusing Soundbuffer issues...  (Read 3489 times)

0 Members and 2 Guests are viewing this topic.

bglaze

  • Newbie
  • *
  • Posts: 46
    • View Profile
Reusing Soundbuffer issues...
« on: November 03, 2011, 12:51:32 am »
Okay, so in order to play multiple instances of the same sound over top of each other (such as laser shots or explosions), I have created a vector to contain the Sound objects.

A SoundBuffer object matching each of my wav files is stored as a member in my file manager object and is always alive.

First I call my PlaySound function:

Code: [Select]
PlaySound(loads.MyBuffer);

This is my complete PlaySound function:

Code: [Select]
void Game::PlaySound(sf::SoundBuffer& buffer){
    soundbox.push_back(sf::Sound(buffer));
    soundbox[soundbox.size()-1].Play();
}


Then, I have a function that sits in my main loop that checks if each sound has finished playing, and if it has, it gets destroyed. Here is that function:

Code: [Select]
void Game::DestroySounds(){
    for(std::vector<sf::Sound>::iterator iter = soundbox.begin(); iter != soundbox.end(); ){
        if(!iter->GetStatus()){
            iter = soundbox.erase(iter);
        }else{
            ++iter;
        }
    }
}


All this works. However, as soon as one of the Sound objects is erased from the vector, the most recent Sounds that share the same SoundBuffer as the erased Sound are stopped short if they were still playing.

Any advice?

bglaze

  • Newbie
  • *
  • Posts: 46
    • View Profile
Reusing Soundbuffer issues...
« Reply #1 on: November 03, 2011, 03:48:46 am »
I think this block is the cause of my sounds getting cut short.

Code: [Select]
if(!iter->GetStatus()){
    iter = soundbox.erase(iter);
}else{
    ++iter;
}


Because, if I comment out this code, everything works fine, however my sounds aren't getting destroyed which means I will cap them out very soon.

I need to figure out a way to only remove them from the vector when they truly have finished playing.

Any idea of how I might go about this other than:

Code: [Select]
if(!iter->GetStatus())

?[/code]

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Reusing Soundbuffer issues...
« Reply #2 on: November 03, 2011, 08:06:35 am »
When you erase a sf::Sound instance from your vector, all the following ones are moved in memory to fill the gap. "Moved" means that new instances are created by copy, and old ones are destroyed. And SFML is not able to copy the "playing status" of a sound ;)

Three solutions:
- use a container that doesn't move its elements when one of them is removed (std::list)
- store pointers to sf::Sound
- leave "empty" items in your vector instead of erasing them, and reuse them when you have a new sound instead of appending a new item.
Laurent Gomila - SFML developer

bglaze

  • Newbie
  • *
  • Posts: 46
    • View Profile
Reusing Soundbuffer issues...
« Reply #3 on: November 03, 2011, 11:04:16 am »
You rock, Laurent. Thanks for explaining how the vector was working against my purposes. I have switched to a list, and I am good to go!

Sorry for the double post!