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

Author Topic: sf::Sound stopping playing on function return  (Read 2772 times)

0 Members and 1 Guest are viewing this topic.

GreenyUk

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
sf::Sound stopping playing on function return
« on: October 02, 2015, 02:27:50 pm »
Hi,

Having some problems with playing a sound. I have a small audio component that handles the playing of sounds:

AudioComponent.h

#pragma once

#include "Component.h"
#include <SFML\Audio.hpp>
#include <memory>

class AudioComponent : public Component
{
public:

        /**
         * Default Constructor.
         */

        AudioComponent();

        /**
         * Sets the sound buffer.
         * @param buffer An existing buffer wrapped in a unique pointer.
         * @return True if successfully.
         */

        bool SetSoundBuffer(std::unique_ptr<sf::SoundBuffer> buffer);

        /**
        * Sets the sound buffer.
        * @param filePath The location of the sound file to load.
        * @return True if successfully.
        */

        bool SetSoundBuffer(std::string filePath);

        /**
         * Plays the sound that's currently set.
         */

        void Play();

private:
        /**
         * The components sound buffer.
         */

        std::unique_ptr<sf::SoundBuffer> buffer;

        /**
         * The main sound object.
         */

        sf::Sound sound;
};
 

AudioComponent.cpp

#include "AudioComponent.h"

/** Default Constructor. */
AudioComponent::AudioComponent()
{
        this->buffer = std::make_unique<sf::SoundBuffer>();
}

/** Sets the sound buffer. */
bool AudioComponent::SetSoundBuffer(std::unique_ptr<sf::SoundBuffer> buffer)
{
        this->buffer = std::move(buffer);
        this->sound.setBuffer(*this->buffer);

        return true;
}

/** Sets the sound buffer. */
bool AudioComponent::SetSoundBuffer(std::string filePath)
{
        if (this->buffer->loadFromFile(filePath))
        {
                this->sound.setBuffer(*this->buffer);
                return true;
        }
        else
        {
                return false;
        }
}

/** Plays the sound that's currently set. */
void AudioComponent::Play()
{
        this->sound.play();
}
 

This code doesn't work, and no sound is played. After some playing I've found it's returning from the Play() function that is stopping the sounds. It took me a while to look there as I understand sf::Sound and sf::Music both create their own threads. If I hang around in the Play() function by appending a while statement at the end:

/** Plays the sound that's currently set. */
void AudioComponent::Play()
{
        this->sound.play();

        while(true){};
}
 

As I understand it, a common reason for this is that the sound buffer goes out of scope and gets destroyed, but it's a member variable wrapped in a std::unique_ptr in this case.

Can anybody shed any light here? There must be something I'm missing as to why it's stopping when the function returns.

GreenyUk

  • Newbie
  • *
  • Posts: 7
    • View Profile
    • Email
Re: sf::Sound stopping playing on function return
« Reply #1 on: October 02, 2015, 02:40:48 pm »
After more playing it seems wrapping sf::Sound or sf::SoundBuffer in a unique_ptr is what's causing this behaviour.

I don't know enough to know what's happening behind the scenes here, but using raw pointers instead works just fine. I presume it's something to do with the scope a unique_ptr enforces?

Anywho, raw pointers on both my sf::Sound and sf::SoundBuffer fixed this issue. I now just need to make sure they get deleted!

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Sound stopping playing on function return
« Reply #2 on: October 02, 2015, 03:30:21 pm »
Whether you use std::unique_ptr, a raw pointer or an instance variable doesn't matter, as long as you initialize them immediately and destroy them in the destructor (automatically except for raw pointers). Avoid raw pointers for ownership, see my article about RAII.

It's a bit difficult to know exactly what you mean. There's no reason why the sound should stop playing at function exit, as it's not a local variable. Can you provide a minimal complete example?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything