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

Author Topic: Sounds stop playing when other Sounds are deleted?  (Read 1871 times)

0 Members and 1 Guest are viewing this topic.

GarrickW

  • Jr. Member
  • **
  • Posts: 50
    • View Profile
Sounds stop playing when other Sounds are deleted?
« on: June 06, 2013, 09:13:58 pm »
So I'm not 100% sure what is going wrong here, but the following code is not working as expected.

void Cycle(float Time, float Pitch)
{
    //Reduce the timer
    m_PlayTimer -= Time;

    //If it's zero, play the sample
    if (m_PlayTimer <= 0.0)
    {
        //Add the sound!
        m_SoundList.push_back(sf::Sound());
        unsigned short NewSound = m_SoundList.size() - 1;
        m_SoundList[NewSound].setBuffer(*SoundManager::GetSoundBuffer(1));
        m_SoundList[NewSound].setVolume(30.0);
        m_SoundList[NewSound].setPitch(Pitch);
        m_SoundList[NewSound].play();

        //Restore a positive value to the timer
        m_PlayTimer = 1.0;
    }

    //Cull finished sounds
    for (unsigned int ii = 0; ii < m_SoundList.size(); ++ii)
    {
        //Test whether the sound is finished or not; if so, remove it
        if (m_SoundList[ii].getStatus() == sf::Sound::Status::Stopped)
        {
            m_SoundList.erase(m_SoundList.begin() + ii);
            std::cout << "Sound deleted!\n";

            //If ii is the same as the size, there are no further sounds
            if (ii == m_SoundList.size())
            {
                break;
            }
            //Otherwise, there are further sounds!  Decrement ii so as not to skip any
            else
            {
                --ii;
            }
        }
    }
}

What happens is that sometimes, when one Sound finishes after another has started (I also modify the pitch of the sound, so the lengths of each sf::Sound are slightly different), both sounds are deleted in the same call, which kills the newer sound before it has had a chance to play out.  It's as though the algorithm thinks that both sf::Sound objects return Stopped upon calling getStatus().

Any idea what might be causing this, and how I can get things to work as expected?

GarrickW

  • Jr. Member
  • **
  • Posts: 50
    • View Profile
Re: Sounds stop playing when other Sounds are deleted?
« Reply #1 on: June 07, 2013, 12:11:14 pm »
Hm, so I solved the problem by using an std::vector<sf::Sound*> as a container, so pointers instead of objects.  Otherwise everything remained the same (obviously, I delete the object before disposing of its pointer in the culling loop, too).  Not sure why that worked, but it did.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Sounds stop playing when other Sounds are deleted?
« Reply #2 on: June 07, 2013, 12:43:30 pm »
When std::vector grows, it may relocate all its objects in memory. This is not good for sf::Sound objects, they must stay alive while they are played.

std::vector<sf::Sound*> is a bad idea because you introduce manual memory management. If you really needed that, std::vector<std::unique_ptr<sf::Sound>> would be more appropriate, since it takes care of the memory.

However, you should rather consider a different STL container which does not have this problem, or use reserve(). The container adapter std::queue is quite appropriate for sounds, if you need more features you can directly use the underlying std::deque.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: